Apakah mungkin untuk menyimpan konten konsol virtual Linux dan scrollback dalam file?

21

Saya memiliki skrip berjalan jangka panjang dan saya lupa untuk mengarahkan ulang outputnya ke file. Saya dapat melihatnya di terminal, tetapi dapatkah saya menyimpannya di file?

Saya tidak meminta tee, redirection output (misalnya >, >>) dll - perintah telah dimulai, dan saya tidak dapat menjalankannya lagi. Saya perlu menyimpan output yang sudah dihasilkan. Jika saya bisa melihatnya di layar saya, ini disimpan / disimpan dalam cache / buffered. Dimana?

screendump, /dev/vcsXdan seterusnya memungkinkan saya untuk hanya menyimpan layar terakhir pada output terminal (bukan saat ini! - terminal bergulir tidak membantu).

Ini ada di konsol virtual Linux, bukan emulator terminal X11 seperti gnome-terminaldengan mouse dan barang lainnya.

Juri
sumber
1
Ya, karena Anda bisa melihatnya, itu ada di suatu tempat. Sayangnya, di suatu tempat ada bingkai penyangga perangkat keras untuk tampilan. Mungkin akan lebih mudah untuk menyalinnya dengan tangan daripada mencabutnya dari perangkat keras layar.
msw
Menarik! Tapi ... itu hilang di suatu tempat, seperti di /dev/, kan? Kalau tidak, Anda sudah menulis bagaimana mencapainya.
Juri

Jawaban:

19

/dev/vcs[a]<n>hanya akan memberi Anda layar penuh-penuh bahkan jika Anda telah menggulir ke atas, tetapi pilihan ioctl()seperti yang digunakan oleh gpmakan memungkinkan Anda untuk membuang layar yang saat ini ditampilkan bahkan ketika Anda sudah menggulir ke atas.

Jadi bisa Anda lakukan:

sleep 3; perl -e '
  require "sys/ioctl.ph";
  # copy:
  ioctl(STDIN, &TIOCLINUX, $arg = pack("CS5", 2, 1, 1, 80, 25, 2));
  # paste:
  ioctl(STDIN, &TIOCLINUX, $arg = "\3")'; cat > file

Sesuaikan 80 dan 25 dengan lebar dan tinggi layar Anda yang sebenarnya.

Ini sleep 3memberi Anda waktu untuk menggulir ke atas (dengan Shift+PageUP) ke layar aktual yang ingin Anda buang. cat > filemengarahkan ulang pasta ke file. Akhiri dengan Ctrl+D.

Lihat console_ioctl(4)detailnya.

Jika Anda telah gpmmenginstal dan menjalankan, Anda dapat melakukan pemilihan dengan mouse.

Scrollback dan seleksi konsol virtual Linux sangat terbatas dan cukup menjengkelkan (karena ketika Anda mengganti konsol, Anda kehilangan seluruh scrollback). Ke depan, saya sarankan Anda menggunakan hal-hal seperti GNU screenatau tmuxdi dalamnya (Saya pribadi menggunakannya di terminal yang bahkan lebih mampu). Dengan mereka, Anda dapat memiliki scrollback yang lebih besar yang dapat dicari dan dengan mudah membuangnya ke file (dan bahkan mencatat semua output terminal, ditambah semua barang lain yang datang dengan multiplexer terminal tersebut).


Seperti untuk mengotomatisasi proses untuk membuang seluruh buffer scrollback, itu harus dimungkinkan dalam beberapa kondisi, tetapi cukup sulit karena API sangat terbatas. Ada yang tidak berdokumen ioctl(TIOCLINUX, subcode = 13) untuk menggulir konsol virtual saat ini dengan beberapa offset (negatif untuk menggulir ke atas, positif untuk menggulir ke bawah).

Namun tidak ada cara (yang saya tahu) untuk mengetahui ukuran saat ini dari buffer scrollback. Jadi sulit untuk mengetahui kapan Anda telah mencapai bagian atas buffer itu. Jika Anda mencoba menggulir melewatinya, layar tidak akan bergeser sebanyak dan tidak ada cara yang dapat diandalkan untuk mengetahui seberapa banyak layar sebenarnya telah digulir.

Saya juga menemukan perilaku bergulir ioctl tidak menentu (setidaknya dengan konsol VGA), di mana bergulir dengan kurang dari 4 baris hanya bekerja sesekali.

Skrip di bawah ini tampaknya berfungsi untuk saya pada konsol penyangga bingkai (dan kadang-kadang pada yang VGA) asalkan penyangga scrollback tidak mengandung urutan garis identik yang lebih panjang dari satu layar plus satu baris.

Ini cukup lambat karena menggulirkan satu baris pada satu waktu, dan perlu menunggu 10 ms untuk bukti ketika membaca setiap layar dump.

Untuk digunakan sebagai that-script > filedari dalam konsol virtual.

#! /usr/bin/perl
require "sys/ioctl.ph";
($rows,$cols) = split " ", `stty size`;
$stty = `stty -g`; chomp $stty;
system(qw(stty raw -echo icrnl min 0 time 1));

sub scroll {
  ioctl(STDIN, &TIOCLINUX, $arg = pack("Cx3l", 13, $_[0])) or die "scroll: $!";
}
sub grab {
  ioctl(STDIN, &TIOCLINUX, $arg = pack("CS5", 2, 1, 1, $cols, $rows, 2)) or die "copy: $!";
  ioctl(STDIN, &TIOCLINUX, $arg = "\3") or die "paste: $!";
  return <STDIN>;
}
for ($s = 0;;$s--) {
  scroll $s if $s;
  @lines = grab;
  if ($s) {
    last if "@lines" eq "@lastlines";
    unshift @output, $lines[0];
  } else {
    @output = @lines;
  }
  @lastlines = @lines;
}
print @output;
exec("stty", $stty);
Stéphane Chazelas
sumber
0

https://github.com/jerome-pouiller/reredirect/ mungkin menjadi pilihan?

Deskripsi:

reredirect adalah utilitas untuk mengambil program yang sedang berjalan dan melampirkan outputnya (output standar dan output kesalahan) ke file atau proses lain.

Sintaksnya adalah sebagai berikut:

reredirect -m FILE PID
Adionditsak
sumber
7
Ini tidak menyimpan output yang sudah dihasilkan seperti yang diminta OP, hanya output baru yang akan dialihkan ke suatu tempat.
jimmij
1
Itu benar ...
Adionditsak
Jadi, jika program saya sudah selesai, saya hanya bisa mengambil foto tampilan saya?
Juri