É possível salvar o conteúdo do console virtual do Linux e o scrollback em um arquivo?

21

Eu tenho um script de longo prazo e esqueci de redirecionar sua saída para um arquivo. Eu posso vê-lo em um terminal, mas posso salvá-lo em um arquivo?

Não estou pedindo tee , redirecionamento de saída (por exemplo, > , >> ) etc - o comando foi iniciado e não posso executá-lo novamente. Eu preciso salvar a saída já gerada. Se eu puder vê-lo no meu monitor, ele está em algum lugar armazenado / armazenado em cache / em buffer. Onde?

screendump , /dev/vcsX e assim por diante me permite salvar apenas a última tela na saída do terminal (o terminal de rolagem atual não ajuda).

Isso está em um console virtual Linux, não em um emulador de terminal X11 como gnome-terminal com mouse e outras coisas boas.

    
por Jury 01.02.2016 / 11:19

2 respostas

19

/dev/vcs[a]<n> só fará com que você chegue à última tela cheia, mesmo que tenha rolado para cima, mas a seleção ioctl() s usada por gpm permitirá que você salve a tela exibida no momento mesmo quando você tiver rolou para cima.

Então você pode fazer:

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 = "")'; cat > file

Ajuste o 80 e o 25 à sua largura e altura real da tela.

O sleep 3 lhe dá tempo para rolar para cima (com Shift + PageUP ) para a tela real que você deseja despejar. cat > file redireciona a pasta para file . Termine com Ctrl + D .

Veja console_ioctl(4) para detalhes.

Se você tiver gpm instalado e em execução, poderá fazer essa seleção com o mouse.

O scrollback e a seleção do console virtual do Linux são muito limitados e bastante irritantes (quando você troca o console, perde todo o scrollback). Indo adiante, eu sugiro que você use coisas como GNU screen ou tmux dentro dele (eu pessoalmente as uso em terminais ainda mais capazes). Com eles, você pode ter pergaminhos pesquisáveis maiores e despejá-los facilmente em arquivos (e até registrar toda a saída do terminal, além de todas as outras vantagens que vêm com esses multiplexadores de terminal).

Como para automatizar o processo para despejar o buffer de rolagem inteira, ele deve ser possível sob algumas condições, mas é bastante difícil, pois a API é muito limitada. Há um ioctl não documentado (TIOCLINUX, subcódigo = 13) para rolar o console virtual atual por algum deslocamento (negativo para rolar para cima, positivo para rolar para baixo).

No entanto, não há nenhuma maneira (que eu saiba) de saber o tamanho atual do buffer de rolagem. Por isso, é difícil saber quando você chegou ao topo desse buffer. Se você tentar passar por ele, a tela não será deslocada em quantidade suficiente e não haverá uma maneira confiável de saber quanto a tela realmente rolou.

Eu também acho o comportamento da rolagem ioctl irregular (pelo menos com o console VGA), onde a rolagem de menos de 4 linhas funciona apenas ocasionalmente.

O script abaixo parece funcionar para mim em consoles de buffer de quadros (e ocasionalmente em VGA), desde que o buffer de rolagem não contenha sequências de linhas idênticas mais longas que uma tela mais uma linha.

É bem lento, porque rola uma linha por vez e precisa esperar 10 ms por vez ao ler cada dump de tela.

Para ser usado como that-script > file de dentro do console 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 = "") 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);
    
por 01.02.2016 / 13:14
0

link pode ser uma opção?

Descrição:

reredirect is a utility for taking an existing running program and attaching its outputs (standard output and error output) to files or another process.

A sintaxe é a seguinte:

reredirect -m FILE PID
    
por 01.02.2016 / 11:47

Tags