【发布时间】:2017-10-01 08:45:58
【问题描述】:
我正在运行一个多小时内产生大量输出的代码。在执行期间,我使用tee 将我的输出记录到一个文件中。然而,仍然发送到我的终端的大量输出有点麻烦,所以我做了一个小函数ShowLastLines,我可以在哪里管道我的输出,它将只显示最后 15 行输出和实时更新。
这是脚本:
function ShowLastLines {
numberoflines=15
i=1
while read var
do
echo $var
if [ $i -gt $numberoflines ]
then
tput sc && tput cuu $(( $numberoflines +1 )) && tput dl 1 && tput rc && tput cuu 1
fi
(( i++ ))
done
}
实际上我是这样使用它的:
( long code ) 2>&1 | tee output.log | ShowLastLines
这按预期工作得很好,但是我想再添加一个功能,即当我点击空格键时我想暂停输出(在ShowLastLines,当然不是在原始执行中)(例如调查一些细节我注意到),并在我再次按空格键时让它继续(它将赶上执行输出)。
我尝试了一些东西,但到目前为止还没有成功。我相信可以通过使用stty(如this thread)将标准输入置于非阻塞模式来完成:
stty -echo -icanon time 0 min 0
但我无法将它与我现有的 read 结合起来。
一个重要的附带说明:我在 AFS 集群上,所以由于不同机器之间的同步是如何实现的,所以在计算完成之前我无法访问日志文件(由 tee 编写)(我知道否则在日志文件上使用tail -f 会更容易)。
Ps:最有用的实现是,当按空格键暂停输出时,可以在输出中向上滚动以显示之前的行。欢迎提出任何建议,但我意识到这可能需要完全不同的实现,这可能会增加大量计算开销,所以我很高兴有一个通过空格键简单暂停的解决方案。
【问题讨论】:
-
您没有使用可以发送标准流控制信号(通常分别为
^S和^Q来暂停和继续输出)的终端仿真器(例如xterm)吗?终端模拟器通常有一个回滚缓冲区(您通常也可以配置要存储多少回滚)。 -
另外,一些通用的脚本建议:您可以通过将相关输出存储在循环外的变量中来减少您调用的
tput命令的数量。 -
@TobySpeight 我在 Ubuntu 上,通过 ssh 连接到批处理集群。你是什么意思将相关输出存储在变量中?代码的总输出是 >20k 行。
-
我的意思是
tput sc等每次循环都会产生相同的输出,所以你可以next=$(tput sc && tput cuu $(( $numberoflines +1 )) && ...); while read var; do echo; if; then echo "$next"; fi; done。但我仍然看不到你的脚本在做什么,而你的终端不能为你做。 -
我的工作流程如下。我有一个提交 24 次计算的脚本,每一次计算大约需要一个小时,并且有 20k 行输出。我早上开始这个脚本,第二天再回来查看。现在,通常只有每个计算的最后一行输出是相关的,这是不可能在所有输出之间找到的(一天后将有 500k 行代码输出;现在尝试找到每个最后一行 - 所以每行一行20k-之间)。所以我最初所做的是将每个计算写入日志,当计算完成后,我输出最后一行......