Ist es möglich, den Inhalt der virtuellen Linux-Konsole und den Bildlauf in einer Datei zu speichern?

21

Ich habe ein langfristig laufendes Skript und habe vergessen, die Ausgabe in eine Datei umzuleiten. Ich kann es in einem Terminal sehen, aber kann ich es in einer Datei speichern?

Ich frage nicht , für tee, die Umleitung der Ausgabe (zB >, >>) usw. - der Befehl hat begonnen, und ich kann es nicht wieder laufen. Ich muss die bereits generierte Ausgabe speichern. Wenn ich es auf meinem Display sehen kann, ist es irgendwo gespeichert / zwischengespeichert / gepuffert. Woher?

screendump, /dev/vcsXund so weiter kann ich nur den letzten Bildschirm der Terminalausgabe speichern (nicht den aktuellen! - Scroll-Terminal hilft nicht).

Dies ist auf einer virtuellen Linux-Konsole, nicht auf einem X11-Terminalemulator wie gnome-terminalbei einer Maus und anderen Extras.

Jury
quelle
1
Ja, da Sie es sehen können, ist es irgendwo. Leider ist das irgendwo der Hardware Frame Buffer für das Display. Es wäre wahrscheinlich einfacher, es von Hand zu transkribieren, als es aus der Display-Hardware herauszureißen.
msw
Interessant! Aber ... es fehlt irgendwo, wie in /dev/, oder? Ansonsten haben Sie geschrieben, wie Sie es erreichen.
Jury

Antworten:

19

/dev/vcs[a]<n>Sie erhalten nur den letzten Bildschirm, auch wenn Sie einen Bildlauf durchgeführt haben. Mit der Auswahl ioctl()von gpmkönnen Sie den aktuell angezeigten Bildschirm auch dann ausgeben, wenn Sie einen Bildlauf durchgeführt haben.

Sie können also Folgendes tun:

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

Stellen Sie die 80 und 25 auf Ihre tatsächliche Bildschirmbreite und -höhe ein.

Das sleep 3gibt Ihnen Zeit , um nach oben (mit Shift+PageUP) dem eigentlichen Bildschirm Sie dump möchten. cat > fileleitet die Paste weiter zu file. Beende es mit Ctrl+D.

Siehe console_ioctl(4)für weitere Einzelheiten.

Wenn Sie gpminstalliert haben und ausgeführt werden, können Sie diese Auswahl mit der Maus vornehmen.

Der Scrollback und die Auswahl der virtuellen Linux-Konsole sind sehr begrenzt und ziemlich ärgerlich (wenn Sie die Konsole wechseln, verlieren Sie den gesamten Scrollback). Zukünftig würde ich vorschlagen, dass Sie Dinge wie GNU screenoder tmuxinnerhalb davon verwenden (ich persönlich benutze sie in noch leistungsfähigeren Terminals). Mit ihnen können Sie größere durchsuchbare Scrollbacks haben und diese einfach in Dateien speichern (und sogar die gesamte Terminal-Ausgabe sowie alle anderen Extras protokollieren, die mit diesen Terminal-Multiplexern geliefert werden).


Die Automatisierung des Prozesses zum Speichern des gesamten Bildlaufpuffers sollte unter bestimmten Bedingungen möglich sein, ist jedoch recht schwierig, da die API sehr begrenzt ist. Es gibt eine undokumentierte ioctl(TIOCLINUX, Subcode = 13), um die aktuelle virtuelle Konsole um einen gewissen Versatz zu scrollen (negativ zum Scrollen nach oben, positiv zum Scrollen nach unten).

Es gibt jedoch keine Möglichkeit (die ich kenne), die aktuelle Größe des Scrollback-Puffers zu ermitteln. Es ist also schwer zu wissen, wann Sie die Spitze dieses Puffers erreicht haben. Wenn Sie versuchen, daran vorbei zu scrollen, wird der Bildschirm nicht so stark verschoben, und es gibt keine verlässliche Möglichkeit, festzustellen, um wie viel der Bildschirm tatsächlich gescrollt hat.

Ich finde auch das Verhalten des Bildlaufs unregelmäßig (zumindest mit der VGA-Konsole), wo das Scrollen um weniger als 4 Zeilen nur gelegentlich funktioniert.

Das folgende Skript scheint für mich auf Frame-Buffer-Konsolen (und gelegentlich auf VGA-Konsolen) zu funktionieren, vorausgesetzt, der Scrollback-Buffer enthält keine Sequenzen identischer Zeilen, die länger als ein Bildschirm plus eine Zeile sind.

Es ist ziemlich langsam, da es zeilenweise einen Bildlauf durchläuft und 10 ms auf eof warten muss, wenn jedes Bildschirmabbild gelesen wird.

Verwendung that-script > fileab der virtuellen Konsole.

#! /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
quelle
0

https://github.com/jerome-pouiller/reredirect/ könnte eine Option sein?

Beschreibung:

reredirect ist ein Dienstprogramm zum Übernehmen eines vorhandenen laufenden Programms und Anhängen seiner Ausgaben (Standardausgabe und Fehlerausgabe) an Dateien oder einen anderen Prozess.

Die Syntax lautet wie folgt:

reredirect -m FILE PID
Adionditsak
quelle
7
Dadurch wird die bereits generierte Ausgabe nicht als OP-Anforderung gespeichert, sondern nur die neue Ausgabe wird irgendwo umgeleitet.
Jimmy
1
Das ist wahr ...
Adionditsak
Wenn mein Programm bereits beendet ist, kann ich nur ein Foto von meinem Display aufnehmen?
Jury