我正在开发一个向stdout发送大量输出的程序,但我希望能够轻松地告诉程序正在做什么。我已经看到一些程序显示脚本或程序的输出,但控制台上的最后一行是“保留”,这意味着命令的输出显示在屏幕上,但是最后一行(或两行,或者很多) )保留用于静态或偶尔更改的状态文本(例如Building <xxxxxx>...
)。这样,可以从脚本/程序中看到输出以进行调试/故障排除,但也可以快速浏览并查看程序的状态。 有没有办法通过shell脚本实现这一目标?我不介意使用内置系统工具(例如awk
)来格式化文本,只要使用的工具常见于大多数系统。如果可能的话,我也想避免使用ncurses
和其他库。
如果你仍然不明白我在说什么,我会试着在这里说明一下:
make -gcc -NOFLAGS -someotherGibberishHere Component1afdjadfjfadkladfjk make -gcc -NOFLAGS -someotherGibberishHere Component2afdjadfjfadkladfjk make -gcc -NOFLAGS -someotherGibberishHere Component3afdjadfjfadkladfjk make -gcc -NOFLAGS -someotherGibberishHere Component4afdjadfjfadkladfjk make -gcc -NOFLAGS -someotherGibberishHere Component5afdjadfjfadkladfjk make -gcc -NOFLAGS -someotherGibberishHere Component6afdjadfjfadkladfjk make -gcc -NOFLAGS -someotherGibberishHere Component7afdjadfjfadkladfjk make -gcc -NOFLAGS -someotherGibberishHere Component8afdjadfjfadkladfjk make -gcc -NOFLAGS -someotherGibberishHere Component9afdjadfjfadkladfjk make -gcc -NOFLAGS -someotherGibberishHere Component10afdjadfjfadkladfjk make -gcc -NOFLAGS -someotherGibberishHere Component11afdjadfjfadkladfjk . . (etc.) . ------------------------------------------------------------------------ Installing component 11/134...
在这个特定的例子中,即使控制台输出开始滚动,我也希望“安装组件11/134 ......”这一行保持在那里。最好,我也想把这条线保持在它上面。
这样,一旦我们深入了解程序,通常shell会开始滚动,我们仍然会看到:
. . (more lines of output here) . make -gcc -NOFLAGS -someotherGibberishHere Component58afdjadfjfadkladfjk make -gcc -NOFLAGS -someotherGibberishHere Component59afdjadfjfadkladfjk make -gcc -NOFLAGS -someotherGibberishHere Component60afdjadfjfadkladfjk make -gcc -NOFLAGS -someotherGibberishHere Component61afdjadfjfadkladfjk make -gcc -NOFLAGS -someotherGibberishHere Component62afdjadfjfadkladfjk make -gcc -NOFLAGS -someotherGibberishHere Component63afdjadfjfadkladfjk make -gcc -NOFLAGS -someotherGibberishHere Component64afdjadfjfadkladfjk make -gcc -NOFLAGS -someotherGibberishHere Component65afdjadfjfadkladfjk make -gcc -NOFLAGS -someotherGibberishHere Component66afdjadfjfadkladfjk ------------------------------------------------------------------------ Installing component 66/134...
答案 0 :(得分:3)
可能值得研究tput
的功能。
以下内容可能构成解决方案的开始,始终在屏幕底部打印状态行:
numlines=$(tput lines)
numcols=$(tput cols)
numcols=$(expr $numcols - 1)
separator_line=$(for i in $(seq 0 $numcols);do printf "%s" "-";done;printf "\n")
tput cup $numlines
echo $separator_line
echo <your status line>
这种逻辑的目的是:
计算屏幕上有多少行并移至底部
计算出多少列并构建分隔线以跨越那么多列
打印分隔线,然后打印状态行
话虽如此,我确信必须有一种更优雅的方式来实现你想要做的事情......
答案 1 :(得分:3)
虽然它需要具有客户端依赖关系,但有一种方法可以使用screen
进行此操作。
#!/bin/bash
# Check if script was started in our screen session
if [ -z "$INTERNAL_INIT_SCRIPT" ]; then
# Create temporary screen config file to avoid conflicts with
# user's .screenrc
screencfg=$(mktemp)
# Show status line at bottom of terminal
echo hardstatus alwayslastline > "$screencfg"
# Start script in a new screen session
INTERNAL_INIT_SCRIPT=1 screen -mq -c "$screencfg" bash -c "$0"
# Store screen return code
ret=$?
# Remove temporary screen config file
rm "$screencfg"
# Exit with the same return code that screen exits with
exit $ret
fi
total=134
function set_status {
screen -X hardstatus string "[$1/$total] $2"
}
# Prints "[1/134] Installing jq..." to the status line
set_status 1 'Installing jq...'
# Install some component
我在我用来初始化Fedora服务器的脚本中使用它,我在DigitalOcean上启动了。这是实践中的样子:
同样,虽然它确实涉及安装screen
,但它是一种常用的工具,并且为此目的使用它非常容易。
答案 2 :(得分:0)
正如Lindsay Winkler's answer建议的那样,tput
可能会做你想要的,如果你的终端(模拟器)支持它。
tput
可用的功能由terminfo
中定义的#!/bin/bash
if tput hs ; then
tput tsl
echo -n This is the status line
tput fsl
else
echo Sorry, there is no status line
fi
定义。
这样的事情应该有效(如果有的话):
tput
(它为我打印错误信息。)
您可以使用man screen
在底行打印文本,但正常输出只会覆盖它(除非您仔细控制写入屏幕的内容)。
GNU屏幕命令也使用状态行,如果终端不支持,可能会模拟一个状态行。 screen
了解详情。但{{1}}倾向于将其用于自己的消息(如果可用),并且您似乎不想对用户强加要求。