我的脚本执行如下操作:
while :;
clear
do_a_lot_of_output_here
sleep 1
done
Run Code Online (Sandbox Code Playgroud)
当我清除和输出时,是否有任何选项可以防止屏幕闪烁?我想像在watch命令中那样做(但它是用 写的C)。有什么建议吗?
clear | hexdump -C
00000000 1b 5b 48 1b 5b 32 4a |.[H.[2J|
00000007
Run Code Online (Sandbox Code Playgroud)
附注。我bash只用。
小智 12
帮助防止闪烁的一种方法是在清除屏幕之前获取所有输出,以便在清除和重绘之间有最短的时间。这类似于双缓冲的概念:
while :; do
output=$(do_a_lot_of_output_here)
clear
echo "$output"
sleep 1
done
Run Code Online (Sandbox Code Playgroud)
这并不能完全消除闪烁,但根据我的经验,它发生的频率要低得多。
发生闪烁是因为脚本清除了整个屏幕。如果它覆盖现有文本并仅在必要时清除,则不会有闪烁。
下面是一个例子:
#!/bin/sh
watchit() {
HOME=$(tput cup 0 0)
ED=$(tput ed)
EL=$(tput el)
ROWS=$(tput lines)
COLS=$(tput cols)
printf '%s%s' "$HOME" "$ED"
while true
do
CMD="$@"
${SHELL:=sh} -c "$CMD" | head -n $ROWS | while IFS= read LINE; do
printf '%-*.*s%s\n' $COLS $COLS "$LINE" "$EL"
done
printf '%s%s' "$ED" "$HOME"
sleep 1
done
}
watchit top -b -n 1
Run Code Online (Sandbox Code Playgroud)
它这样做:
ed终端的功能从当前位置打印到屏幕末尾。如果你想处理一个可调整大小的屏幕,你可以在任务移动到ROWS与COLS外环内,例如,
#!/bin/sh
watchit() {
HOME=$(tput cup 0 0)
ED=$(tput ed)
EL=$(tput el)
printf '%s%s' "$HOME" "$ED"
while true
do
ROWS=$(tput lines)
COLS=$(tput cols)
CMD="$@"
${SHELL:=sh} -c "$CMD" | head -n $ROWS | while IFS= read LINE; do
printf '%-*.*s%s\n' $COLS $COLS "$LINE" "$EL"
done
printf '%s%s' "$ED" "$HOME"
sleep 1
done
}
watchit top -b -n 1
Run Code Online (Sandbox Code Playgroud)
因为tput从系统询问当前的屏幕大小。
进一步阅读:
小智 6
闪烁是每次循环清屏时不可避免的结果。您可以将光标移动到屏幕顶部并覆盖旧输出的部分内容。
# You may want to do this if your code is in a script.
unhide_cursor() {
printf '\e[?25h'
}
trap unhide_cursor EXIT
# Hide the cursor (there is probably a much better way to do this)
printf '\e[?25l'
clear
while true ; do
# Move the cursor to the top of the screen but don't clear the screen
printf '\033[;H'
do_a_lot_of_output_here
sleep 1
done
Run Code Online (Sandbox Code Playgroud)
如果您的输出缩小,此脚本将留下工件。它也不太可能是便携式的。我只用 urxvt、xterm 和 st 测试过它。