bash 如何在bash中显示和刷新多行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18362837/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 06:20:36  来源:igfitidea点击:

How to display and refresh multiple lines in bash

bash

提问by user2704404

I am writing a installation script and would like to display the status of the script as it progresses.

我正在编写一个安装脚本,并希望随着脚本的进展显示该脚本的状态。

example:

例子:

var1="pending"
var2="pending"
var3="pending"

print_status () {
echo "Status of Item 1 is: "$var1""
echo "Status of Item 2 is: "$var2""
echo "Status of Item 3 is: "$var3""
}

code that does something and then refreshes the
output above as the status of each variable changes.

回答by Aleks-Daniel Jakimenko-A.

This code should give you the idea:

这段代码应该给你的想法:

while :; do
    echo "$RANDOM"
    echo "$RANDOM"
    echo "$RANDOM"
    sleep 0.2
    tput cuu1 # move cursor up by one line
    tput el # clear the line
    tput cuu1
    tput el
    tput cuu1
    tput el
done

Use man tputfor more info. To see the list of capabilities use man terminfo

使用man tput以获取更多信息。要查看功能列表,请使用man terminfo

回答by Woody Huang

I find another solution which is not mentioned in existing answers. I am developing program for openwrt, and tputis not available by default. The solution below is inspired by Missing tputand Cursor Movement.

我找到了现有答案中未提及的另一种解决方案。我正在为 openwrt 开发程序,tput默认情况下不可用。下面的解决方案受到Missing tputCursor Movement 的启发。

- Position the Cursor:
  3[<L>;<C>H
     Or
  3[<L>;<C>f
  puts the cursor at line L and column C.
- Move the cursor up N lines:
  3[<N>A
- Move the cursor down N lines:
  3[<N>B
- Move the cursor forward N columns:
  3[<N>C
- Move the cursor backward N columns:
  3[<N>D

- Clear the screen, move to (0,0):
  3[2J
- Erase to end of line:
  3[K

- Save cursor position:
  3[s
- Restore cursor position:
  3[u

As for your question:

至于你的问题:

var1="pending"
var2="pending"
var3="pending"

print_status () {
    # add 3[K to truncate this line
    echo "Status of Item 1 is: "$var1"3[K"
    echo "Status of Item 2 is: "$var2"3[K"
    echo "Status of Item 3 is: "$var3"3[K"
}

while true; do 
    print_status
    sleep 1
    printf "3[3A"    # Move cursor up by three line
done

回答by rook

Look at this:

看这个:

while true; do echo -ne "`date`\r"; done

and this:

和这个:

declare arr=(
  ">...."
  ".>..."
  "..>.."
  "...>."
  "....>"
)

for i in ${arr[@]}
do
  echo -ne "${i}\r"
  sleep 0.1
done

回答by Fabio A. Correa

This does not completely solve your problem but might help; to print the status after the execution of each command, modify PS1 like this:

这并不能完全解决您的问题,但可能会有所帮助;要打印每个命令执行后的状态,请像这样修改 PS1:

PS1='$PS1 $( print_status )'

回答by seanmcl

You can use the carriage return to change text on a single status line.

您可以使用回车来更改单个状态行上的文本。

n=0
while true; do
  echo -n -e "n: $n\r"
  sleep 1
  n=$((n+1))
done

If you can put all your counters on one line

如果你能把所有的计数器放在一条线上

n=0
m=100
while true; do
  echo -n -e "n: $n  m: $m\r"
  sleep 1
  n=$((n+1))
  m=$((m-1))
done

This technique doesn't seem to scale to multiple lines, though it does have the benefit over tput that it works on dumb terminals (like Emacs shell).

这种技术似乎不能扩展到多行,尽管它确实比 tput 有优势,因为它适用于哑终端(如 Emacs shell)。