¿Es posible guardar el contenido de la consola virtual de Linux y retroceder en un archivo?

21

Tengo un script en ejecución a largo plazo y olvidé redirigir su salida a un archivo. Puedo verlo en una terminal, pero ¿puedo guardarlo en un archivo?

No estoy pidiendo teeredirección de salida (por ejemplo >, >>etc.), el comando se ha iniciado y no puedo ejecutarlo nuevamente. Necesito guardar la salida ya generada. Si puedo verlo en mi pantalla, está almacenado / almacenado en caché / almacenado en algún lugar. ¿Dónde?

screendump, /dev/vcsXy así sucesivamente, me permite guardar solo la última pantalla en la salida del terminal (¡no el actual! - el terminal de desplazamiento no ayuda).

Esto está en una consola virtual de Linux, no en un emulador de terminal X11 como gnome-terminalcon el mouse y otras cosas.

Jurado
fuente
1
Sí, ya que puedes verlo, está en alguna parte. Desafortunadamente, ese lugar es el buffer de marco de hardware para la pantalla. Probablemente sería más fácil transcribirlo a mano que extraerlo del hardware de la pantalla.
msw
¡Interesante! Pero ... falta en alguna parte, como en /dev/, ¿verdad? De lo contrario, has escrito cómo alcanzarlo.
Jurado

Respuestas:

19

/dev/vcs[a]<n>solo obtendrá la última pantalla completa, incluso si se ha desplazado hacia arriba, pero las selecciones ioctl()utilizadas por gpmle permitirán volcar la pantalla que se muestra actualmente incluso cuando se haya desplazado hacia arriba.

Entonces puedes hacer:

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

Ajuste los 80 y 25 al ancho y alto de su pantalla real.

Esto sleep 3le da tiempo para desplazarse hacia arriba (con Shift+PageUP) a la pantalla real que desea volcar. cat > fileredirige la pasta a file. Terminar con Ctrl+D.

Ver console_ioctl(4)para más detalles.

Si ha gpminstalado y ejecutado, puede hacer esa selección con el mouse.

El desplazamiento hacia atrás y la selección de la consola virtual de Linux son muy limitados y bastante molestos (en el sentido de que al cambiar de consola, se pierde todo el desplazamiento hacia atrás). En el futuro, te sugiero que uses cosas como GNU screeno tmuxdentro de él (personalmente las uso en terminales aún más capaces). Con ellos, puede tener desplazamientos de búsqueda más grandes y volcarlos fácilmente en archivos (e incluso registrar toda la salida del terminal, además de todas las otras ventajas que vienen con esos multiplexores de terminal).


En cuanto a la automatización del proceso para volcar todo el búfer de desplazamiento hacia atrás, debería ser posible en algunas condiciones, pero bastante difícil ya que la API es muy limitada. Hay un indocumentado ioctl(TIOCLINUX, subcódigo = 13) para desplazar la consola virtual actual por algún desplazamiento (negativo para desplazarse hacia arriba, positivo para desplazarse hacia abajo).

Sin embargo, no hay forma (que yo sepa) de saber el tamaño actual del búfer de desplazamiento hacia atrás. Por lo tanto, es difícil saber cuándo has llegado a la cima de ese búfer. Si intentas desplazarte más allá, la pantalla no se desplazará tanto y no hay una manera confiable de saber cuánto se ha desplazado realmente la pantalla.

También encuentro el comportamiento del desplazamiento ioctl errático (al menos con la consola VGA), donde el desplazamiento en menos de 4 líneas funciona solo ocasionalmente.

El siguiente script parece funcionar para mí en las consolas de frame buffer (y ocasionalmente en las VGA) siempre que el buffer de desplazamiento no contenga secuencias de líneas idénticas más largas que una pantalla más una línea.

Es bastante lento porque se desplaza una línea a la vez y necesita esperar 10 ms para eof al leer cada volcado de pantalla.

Para ser utilizado that-script > filedesde dentro de la consola 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
fuente
0

https://github.com/jerome-pouiller/reredirect/ podría ser una opción?

Descripción:

reredirect es una utilidad para tomar un programa en ejecución existente y adjuntar sus salidas (salida estándar y salida de error) a archivos u otro proceso.

La sintaxis es la siguiente:

reredirect -m FILE PID
Adionditsak
fuente
77
Esto no guarda la salida ya generada como OP solicitó, solo la nueva salida se redirigirá a alguna parte.
jimmij
1
Eso es cierto ...
Adionditsak 01 de
Entonces, si mi programa ya terminó, ¿solo puedo tomar una foto de mi pantalla?
Jurado