【问题标题】:Progress bar + ETA on same line with pv command与 pv 命令在同一行上的进度条 + ETA
【发布时间】:2017-12-14 12:42:15
【问题描述】:

简介

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

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

这很好用,但我希望进度条显示在同一行。 This answer 解释了如何做到这一点。

所以我尝试了这个:

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 answered the question,我意识到我还有一个相关的要求:需要保留 stdout,以便可以在下一个管道中使用它。在我的具体情况下,我需要将结果写入文件(即&gt; some-file.txt

【问题讨论】:

    标签: linux bash macos shell pv


    【解决方案1】:

    您输入了错误的命令。

    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 不会从标准输入读取任何内容。

    因为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

    【讨论】:

    • 我不确定我是否完全理解你的意思,但我在命令行上尝试了这个,现在它再次更新了新行的进度(就像我的第一个例子一样)。是否缺少重要的一点?
    • @RolfW。我在echo ; pv 周围添加了一对括号
    • 我注意到了,但我现在发现我的评论不清楚;我的真正意思是我不完全理解你所解释的背后的原理,所以在你的建议下我无法自己理解它。当我按原样尝试您的示例时,它是prints each progression on the next line again,就像我的问题中的第一个代码示例一样。我所追求的是进度条+百分比+ ETA在同一行更新。你知道如何让代码这样工作吗?
    • 就是这样 :) 谢谢!
    • 对于任何感兴趣的人,我还有一个要求是将标准输出写入管道末尾的文件:for (( i = 1 ; i &lt;= 100 ; i++ )); do sleep 1; echo $i; done | (&gt;&amp;2 echo -en "\r"; pv --progress --line-mode --size 100 --eta --timer &gt; /dev/null) &gt; temp.txt。此解决方案抑制标准输出,因此需要解决方法:for (( i = 1 ; i &lt;= 100 ; i++ )); do sleep 1; echo $i &gt;&gt; temp.txt; echo "$1"; done | (&gt;&amp;2 echo -en "\r"; pv --progress --line-mode --size 100 --eta --timer &gt; /dev/null)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-25
    • 1970-01-01
    • 2012-03-07
    • 2012-08-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多