与PV命令在同一条线上的Progress Bar ETA



into

我正在使用管道中的pv命令来显示进度栏。我尝试了一个简单的计数器:

for (( i = 1 ; i <= 100 ; i++ )); do sleep 1; echo $i; done | pv --progress --line-mode --size 100 --eta --timer

这可以正常工作,但是我希望进度栏在同一行上显示。此答案解释了如何做到这一点。

所以我尝试了:

for (( i = 1 ; i <= 100 ; i++ )); do sleep 1; echo $i; done | >&2 echo -en "r"; pv --progress --line-mode --size 100 --eta --timer

它停留在一行上,但现在不再更新ETA。

问题

我如何也可以更新ETA?

更新

现在,Ibug回答了上一节中的问题,我意识到我还有一个相关的要求:需要保留stdout,因此可以在下一个管道中使用。在我的具体情况下,我需要将结果写入文件(即> some-file.txt

您正在输入错误的命令。

for (( i = 1 ; i <= 100 ; i++ )); do sleep 1; echo $i; done | >&2 echo -en "r"; pv --progress --line-mode --size 100 --eta --timer
                                                                               ^

pv之前有一个半龙,因此您实际上是在stdin/stdout上运行的,这是您的终端。您应该对额外的echopv进行分组,以使其从for循环中读取:

for (( i = 1 ; i <= 100 ; i++ )); do sleep 1; echo $i; done | (>&2 echo -en "r"; pv --progress --line-mode --size 100 --eta --timer)

为什么第一个命令不是这种情况?这是因为整个for do done子句被视为一个命令,因此其结果正确地将其管道输送到pv。但是,在第二个命令中,结果将管道输送到echo。您知道,echo没有从stdin中读取任何内容。

由于pv将STDIN引导到Stdout,因此数字也将输出输出到终端,该终端与STDERR的指示混合在一起。要抑制非输出输出,请将其重定向到/dev/null,因此最终命令为

for (( i = 1 ; i <= 100 ; i++ )); do sleep 1; echo $i; done | (>&2 echo -en "r"; pv --progress --line-mode --size 100 --eta --timer) > /dev/null

如果要将输出重定向到文件,只需在命令末尾更改/dev/null

最新更新