我正在制作一个脚本,用于检查某个状态,输出结果,短时间睡眠,然后重新开始一切。输出由多行组成,我希望脚本更新输出,这意味着再次在同一行上打印。它应该适用于Mac和Linux。这就是我到目前为止所做的:
#! /usr/bin/perl
use strict;
print `tput sc`; # Store cursor position
my @lines;
while (1) {
@lines = ();
push(@lines, `tput rc`); # Restore cursor position
push(@lines, `tput ed`); # Clear from cursor to end of screen
push(@lines, `dd if=/dev/urandom bs=1 count=1`); # This is just an example
print @lines;
sleep 1;
}
只要我没有用光标在终端窗口的末尾调用脚本,它就可以正常工作。在后一种情况下,光标在打印后停留在窗口的末尾,因此恢复它的原始位置实际上没有任何效果,下一个输出只是转到新行。
我该如何避免?
我不想调用tput clear
或tput init
,因为这可能会丢失任何先前的命令和输出。我正在考虑滚动窗口,以便在我开始输出之前提示符位于顶行,但这需要当前的光标行,我无法看到如何使用tput
获得该提示。
或者,我可以记住打印的行数,然后使用tput rin
将光标移回。但是,当输出太长并且在两个或多个终端线上断开时,这不起作用。
答案 0 :(得分:3)
通常,执行此类操作的程序要么使用屏幕上的固定位置,要么记住它们输出了多少行并跳回适当的安装位置。
通过简单地向下滚动以使窗口显示为空白,大多数终端仿真窗口响应清除屏幕命令也可能会有所帮助。这意味着之前屏幕上的任何信息仍然可用“高于”。只是不要在每次通过while
循环时清除屏幕。从clear / store组合开始可能正是您所需要的。
您可以尝试使用use Curses
或use Term::ANSIScreen
来更好地控制您的终端,而无需进行光标控制。
额外信用:如果你坚持炮轰光标控制字符串,不要在循环的每次迭代中产生tput
命令。记录它的输出,并为每次传递重新打印。
将您的打印行更改为print @ANSI_control_strings, @lines;
之类的内容可能具有额外的优势,scalar @lines
将准确说明如果您从反引号更改为管道打开,您可能想要跳回多少行