È possibile salvare il contenuto della console virtuale Linux e lo scrollback in un file?


21

Ho uno script in esecuzione a lungo termine e ho dimenticato di reindirizzare il suo output su un file. Posso vederlo in un terminale, ma posso salvarlo in un file?

Non sto chiedendo tee, reindirizzamento dell'output (ad es >. >>) Ecc. - Il comando è stato avviato e non posso eseguirlo di nuovo. Devo salvare l'output già generato. Se riesco a vederlo sul mio display, è da qualche parte memorizzato / memorizzato nella cache / bufferizzato. Dove?

screendump, /dev/vcsXE così via mi permette di salvare solo l'ultima schermata sul terminale di uscita (non l'attuale - lo scorrimento del terminale non aiuta).

Questo è su una console virtuale Linux, non su un emulatore di terminale X11 come gnome-terminalcon il mouse e altri gadget.


1
Sì, poiché puoi vederlo, è da qualche parte. Sfortunatamente, da qualche parte c'è il frame buffer hardware per il display. Probabilmente sarebbe più facile trascriverlo a mano piuttosto che strapparlo dall'hardware del display.
msw,

Interessante! Ma ... Manca da qualche parte, come in /dev/, giusto? Altrimenti, hai scritto come raggiungerlo.
Giuria

Risposte:


19

/dev/vcs[a]<n>ti darà solo l'ultimo schermo pieno anche se hai fatto scorrere verso l'alto, ma la selezione ioctl()usata come gpmti permetterà di scaricare lo schermo attualmente visualizzato anche quando hai fatto scorrere verso l'alto.

Quindi puoi fare:

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

Regola 80 e 25 in base alla larghezza e all'altezza effettive dello schermo.

Il sleep 3dà il tempo di scorrere verso l'alto (con Shift+PageUP) allo schermo vero e proprio che si desidera scaricare. cat > filereindirizza la pasta a file. Finiscilo con Ctrl+D.

Vedi console_ioctl(4)per i dettagli.

Se hai gpminstallato e in esecuzione, puoi fare quella selezione con il mouse.

Lo scrollback e la selezione della console virtuale Linux sono molto limitati e piuttosto fastidiosi (in quanto quando si cambia console, si perde l'intero scrollback). Andando avanti, suggerirei di usare cose come GNU screeno al tmuxsuo interno (le uso personalmente in terminali ancora più capaci). Con loro, puoi avere scrollback più grandi ricercabili e scaricarli facilmente su file (e persino registrare tutto l'output del terminale, oltre a tutte le altre chicche che vengono con quei multiplexer terminali).


Per quanto riguarda l'automazione del processo per scaricare l'intero buffer di scrollback, dovrebbe essere possibile in alcune condizioni, ma abbastanza difficile poiché l'API è molto limitata. È presente un documento non documentato ioctl(TIOCLINUX, sottocodice = 13) per scorrere la console virtuale corrente di un certo offset (negativo per lo scorrimento verso l'alto, positivo per lo scorrimento verso il basso).

Non esiste tuttavia alcun modo (che io conosca) di conoscere la dimensione corrente del buffer di scorrimento. Quindi è difficile sapere quando hai raggiunto la cima di quel buffer. Se si tenta di scorrere oltre, lo schermo non verrà spostato di tanto e non esiste un modo affidabile per sapere da quanto lo schermo è effettivamente passato.

Trovo anche il comportamento dello ioctl a scorrimento irregolare (almeno con la console VGA), dove lo scorrimento di meno di 4 righe funziona solo occasionalmente.

Lo script seguente sembra funzionare per me su console frame buffer (e occasionalmente su VGA) purché il buffer di scrollback non contenga sequenze di linee identiche più lunghe di uno schermo più una linea.

È piuttosto lento perché scorre di una riga alla volta e deve attendere 10 ms per l'espansione durante la lettura di ogni dump dello schermo.

Da utilizzare come that-script > fileall'interno della console virtuale.

#! /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);

0

https://github.com/jerome-pouiller/reredirect/ potrebbe essere un'opzione?

Descrizione:

reredirect è un'utilità per prendere un programma in esecuzione esistente e allegare i suoi output (output standard e output di errore) a file o un altro processo.

La sintassi è la seguente:

reredirect -m FILE PID

7
Questo non salva l'output già generato come richiesto da OP, solo un nuovo output verrà reindirizzato da qualche parte.
jimmij,

1
È vero ...
Adionditsak,

Quindi, se il mio programma è già finito, posso solo scattare una foto del mio display?
Giuria
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.