是否可以将Linux虚拟控制台内容和回滚保存到文件中?


21

我有一个长期运行的脚本,我忘记了将其输出重定向到文件。我可以在终端中看到它,但是可以将其保存到文件中吗?

我不要求tee,输出重定向(例如>>>)等-的命令已经开始了,我不能再运行它。我需要保存已经生成的输出。如果我可以在显示器上看到它,则表明它已存储/缓存/缓冲。哪里?

screendump/dev/vcsX依此类推,这样我只能在终端输出中保存最后一个屏幕(而不是当前屏幕!-滚动终端无济于事)。

这是在Linux虚拟控制台上,而不是X11终端模拟器,如gnome-terminal鼠标和其他好东西。


1
是的,因为您可以看到它,所以它在某个地方。不幸的是,那是显示器的硬件帧缓冲区。用手转录它可能比将其从显示硬件中撕下来要容易得多。
msw 16年

有趣!但是...它在某处丢失了,就像in中/dev/,对不对?否则,您已经写了如何达到它。
陪审团

Answers:


19

/dev/vcs[a]<n>即使您向上滚动,也只会使您最后一个屏幕显示满,但是使用的选择ioctl()s gpm即使在向上滚动时也可以转储当前显示的屏幕。

因此,您可以执行以下操作:

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

将80和25调整为实际的屏幕宽度和高度。

这样sleep 3您就有时间向上滚动(使用Shift+PageUP)到您要转储的实际屏幕。cat > file将粘贴重定向到file。用完成它Ctrl+D

有关console_ioctl(4)详细信息,请参见。

如果已gpm安装并正在运行,则可以使用鼠标进行选择。

Linux虚拟控制台的回滚和选择非常有限且非常烦人(因为当您切换控制台时,会丢失整个回滚)。展望未来,我会建议你使用之类的东西GNU screentmux在它(我个人使用它们更显干练终端)。有了它们,您可以拥有更大的可搜索回滚并将它们轻松转储到文件中(甚至记录所有终端输出以及这些终端多路复用器随附的所有其他功能)。


至于自动转储整个回滚缓冲区的过程,在某些情况下应该可以实现,但是由于API的限制非常困难。有一个未ioctl公开的文档(TIOCLINUX,子代码= 13),用于将当前虚拟控制台滚动一定的偏移量(向上滚动为负,向下滚动为正)。

但是,(我知道)没有办法知道回滚缓冲区的当前大小。因此,很难知道何时到达该缓冲区的顶部。如果您尝试滚动过去,屏幕将不会移动太多,并且没有可靠的方式知道屏幕实际滚动了多少。

我还发现了滚动ioctl不稳定(至少在VGA控制台上)的行为,其中滚动少于4行仅偶尔起作用。

如果回滚缓冲区不包含长于一个屏幕加一行的相同行的序列,则以下脚本在帧缓冲区控制台(有时在VGA缓冲区控制台)上对我来说适用。

这很慢,因为它一次滚动一行,读取每个屏幕转储时需要等待10ms的eof。

that-script > file从虚拟控制台内部使用。

#! /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/可能是一种选择?

描述:

reredirect是一个实用程序,用于获取现有正在运行的程序并将其输出(标准输出和错误输出)附加到文件或其他进程。

语法如下:

reredirect -m FILE PID

7
这不会按照OP的要求保存已生成的输出,只会将新的输出重定向到某个地方。
jimmij '02

1
没错...
Adionditsak

那么,如果我的程序已经完成,我只能拍摄我的显示屏照片吗?
陪审团
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.