我有一个长期运行的脚本,但忘记将其输出重定向到文件。我可以在终端中看到它,但是我可以将它保存到文件中吗?
我不是要求tee
输出重定向(例如>
,>>
)等 - 命令已启动,我无法再次运行它。我需要保存已经生成的输出。如果我可以在我的显示器上看到它,它就在某个地方存储/缓存/缓冲。在哪里?
screendump
,/dev/vcsX
等等允许我只保存终端输出上的最后一个屏幕(不是当前的! - 滚动终端没有帮助)。
这是在 Linux 虚拟控制台上,而不是像gnome-terminal
鼠标和其他好东西一样的 X11 终端模拟器。
Sté*_*las 20
/dev/vcs[a]<n>
即使您向上滚动,也只会让您看到最后一个屏幕,但是使用的 selection ioctl()
sgpm
将允许您转储当前显示的屏幕,即使您已经向上滚动。
所以你可以这样做:
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
Run Code Online (Sandbox Code Playgroud)
将 80 和 25 调整为您的实际屏幕宽度和高度。
这sleep 3
让您有时间(使用Shift+PageUP)向上滚动到要转储的实际屏幕。cat > file
将粘贴重定向到file
. 用 完成它Ctrl+D。
详情请参阅console_ioctl(4)
。
如果您已gpm
安装并运行,则可以使用鼠标进行选择。
Linux 虚拟控制台回滚和选择非常有限且很烦人(因为当您切换控制台时,您会丢失整个回滚)。展望未来,我建议您使用 GNU之类的东西screen
或tmux
在其中使用(我个人在功能更强大的终端中使用它们)。使用它们,您可以拥有更大的可搜索回滚并轻松地将它们转储到文件中(甚至记录所有终端输出,以及这些终端多路复用器附带的所有其他好东西)。
至于自动转储整个回滚缓冲区的过程,在某些情况下应该是可能的,但由于 API 非常有限,因此非常困难。有一个未记录的ioctl
(TIOCLINUX, subcode=13) 可以按某个偏移量滚动当前虚拟控制台(向上滚动为负,向下滚动为正)。
然而,没有办法(我知道)知道回滚缓冲区的当前大小。因此很难知道您何时到达该缓冲区的顶部。如果您尝试滚动通过它,屏幕将不会移动那么多,并且没有可靠的方法知道屏幕实际滚动了多少。
我还发现滚动 ioctl 的行为不稳定(至少在 VGA 控制台中),其中滚动少于 4 行只是偶尔起作用。
如果回滚缓冲区不包含长于一个屏幕加一行的相同行序列,则下面的脚本似乎对我在帧缓冲区控制台(偶尔在 VGA 控制台)上工作。
它很慢,因为它一次滚动一行,并且在读取每个屏幕转储时需要等待 10 毫秒的 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);
Run Code Online (Sandbox Code Playgroud)