在许多Linux程序中,比如curl、wget以及任何带有进度条的程序,它们会每隔一定时间更新底部行。我该如何在bash脚本中实现这个功能?目前我只能使用echo换行,但这并不是我想要的,因为会积累起来。我曾经看到过一个提到"tput cup 0 0"的方法,但我尝试了一下,发现有点怪异。有没有更好的方法呢?
{
for pc in $(seq 1 100); do
echo -ne "$pc%\033[0K\r"
usleep 100000
done
echo
}
"\033[0K"将删除到行尾-以防止进度行在某些时候变短,尽管这可能对你的目的并非必要。
"\r"将把光标移到当前行的开头
echo命令中的-n选项将防止光标向下一行移动
您也可以使用tput cuu1; tput el
(或printf '\e[A\e[K'
)将光标向上移动一行并擦除该行:
for i in {1..100};do echo $i;sleep 1;tput cuu1;tput el;done
printf '\e[A\e[K'
是唯一一个真正解决我的问题的方法!感谢分享! - João Ciocca在linuts的代码示例上进行小变动,将光标移动到当前行的末尾而不是开头。
{
for pc in {1..100}; do
#echo -ne "$pc%\033[0K\r"
echo -ne "\r\033[0K${pc}%"
sleep 1
done
echo
}
printf '\r'
来实现。在这种情况下,没有必要进行光标定位。要实际删除之前的行,而不仅仅是当前行,您可以使用以下bash函数:
# Clears the entire current line regardless of terminal size.
# See the magic by running:
# { sleep 1; clear_this_line ; }&
clear_this_line(){
printf '\r'
cols="$(tput cols)"
for i in $(seq "$cols"); do
printf ' '
done
printf '\r'
}
# Erases the amount of lines specified.
# Usage: erase_lines [AMOUNT]
# See the magic by running:
# { sleep 1; erase_lines 2; }&
erase_lines(){
# Default line count to 1.
test -z "$1" && lines="1" || lines="$1"
# This is what we use to move the cursor to previous lines.
UP='\033[1A'
# Exit if erase count is zero.
[ "$lines" = 0 ] && return
# Erase.
if [ "$lines" = 1 ]; then
clear_this_line
else
lines=$((lines-1))
clear_this_line
for i in $(seq "$lines"); do
printf "$UP"
clear_this_line
done
fi
}
erase_lines 5
来清除终端中的最后5行即可。查看 man terminfo(5) 并查看 "cap-nam" 列。
clr_eol=$(tput el)
while true
do
printf "${clr_eol}your message here\r"
sleep 60
done
'\r'
可以将光标回到行首。因此,只需使用不带换行符 [-n
] 的 echo 命令,然后echo -ne '\r'
就可以回到行首了。 - Matt