bash 如何打印到同一行,覆盖上一行?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18017256/
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:06:47  来源:igfitidea点击:

How to print out to the same line, overriding previous line?

bashshell

提问by nacho4d

Sometimes I see some commands in the terminal that print results to stdout but in the same line. For example wget prints an arrow like below:

有时我会在终端中看到一些命令将结果打印到标准输出,但在同一行中。例如 wget 打印如下箭头:

0[=>        ]100%
0[  =>      ]100%
0[    =>    ]100%
0[      =>  ]100%
0[        =>]100%

but it is printed out to the same line so it looks like the arrow is moving. How can I achieve the same thing in my programs using bash or sh? Do I need to use other tools?

但它被打印到同一行,所以看起来箭头在移动。如何使用 bash 或 sh 在我的程序中实现相同的功能?我需要使用其他工具吗?

UPDATE:

更新:

I know I mentioned wget, which comes by default in linux, GNU based unices ... Is there a general approach that works on BSDs too? (like OSX) -> OK, If I use bash instead of sh then it works :)

我知道我提到了 wget,它在 linux 中默认出现,基于 GNU 的 unices ......是否有适用于 BSD 的通用方法?(如 OSX)-> 好的,如果我使用 bash 而不是 sh 那么它可以工作:)

回答by choroba

Use the special character \r. It returns to the beginning of the line without going to the next one.

使用特殊字符\r。它返回到行的开头而不去下一个。

for i in {1..10} ; do
    echo -n '['
    for ((j=0; j<i; j++)) ; do echo -n ' '; done
    echo -n '=>'
    for ((j=i; j<10; j++)) ; do echo -n ' '; done
    echo -n "] $i"0% $'\r'
    sleep 1
done

回答by fedorqui 'SO stop harming'

You can use \rfor this purpose:

您可以\r为此目的使用:

For example this will keep updating the current time in the same line:

例如,这将在同一行中不断更新当前时间:

while true; do echo -ne "$(date)\r"; done

回答by user1146332

You can also use ANSI/VT100 terminal escape sequencesto achieve this.

您也可以使用它ANSI/VT100 terminal escape sequences来实现这一点。

Here is a short example. Of course you can combine the printfstatements to one.

这是一个简短的例子。当然,您可以将这些printf语句合二为一。

#!/bin/bash

MAX=60
ARR=( $(eval echo {1..${MAX}}) )

for i in ${ARR[*]} ; do 
    # delete from the current position to the start of the line
    printf "\e[2K"
    # print '[' and place '=>' at the $i'th column
    printf "[\e[%uC=>" ${i}
    # place trailing ']' at the ($MAX+1-$i)'th column
    printf "\e[%uC]" $((${MAX}+1-${i}))
    # print trailing '100%' and move the cursor one row up
    printf " 100%% \e[1A\n"

    sleep 0.1
done

printf "\n"

With escape sequences you have the most control over your terminal screen.

使用转义序列,您可以最大程度地控制终端屏幕。

You can find an overview of possible sequences at [1].

您可以在 [ 1] 中找到可能序列的概述。

[1] http://ascii-table.com/ansi-escape-sequences-vt-100.php

[1] http://ascii-table.com/ansi-escape-sequences-vt-100.php