Syc*_*yco 4 bash shell-script pv
我在 Linux 机器上有一个脚本,其中一个奇特的 pv 通过管道传输到第二个 pv,该 pv 计算输出行的子集。
这是脚本:
max=1000
for (( i=0; i<max; i++ )); do
[[ $(shuf -i 1-100 -n 1) -lt 20 ]] && echo REMOVE || echo LEAVE
done | pv -F "%N %b / $(numfmt --to=si $max) %t %p %e" -c -N 'Lookups' -l -s $max \
| grep --line-buffered '^REMOVE' \
| pv -F "%N %b / $(numfmt --to=si $max)" -c -N 'Deletes' -l -s $max \
>/dev/null
stty sane
Run Code Online (Sandbox Code Playgroud)
我期望的是第一个 pv 总是首先显示,第二个总是第二个。
就像这个例子的输出:
$ ./fancy_pv.sh
Lookups: 1.00k / 1.0K 0:00:03 [===============================================================================================================================================================================================================================================================================================================================================================>] 100%
Deletes: 189 / 1.0K
Run Code Online (Sandbox Code Playgroud)
但事实并非如此,有时他们交换位置,我看到这样的事情:
$ ./fancy_pv.sh
Deletes: 199 / 1.0K
Lookups: 1.00k / 1.0K 0:00:03 [===============================================================================================================================================================================================================================================================================================================================================================>] 100%
Run Code Online (Sandbox Code Playgroud)
有时我也会看到这样的事情:
$ ./fancy_pv.sh
Lookups: 321 / 1.0K 0:00:01 [===============================================================================================================> ] 32% ETA 0:00:02
Deletes: 198 / 1.0K
Lookups: 1.00k / 1.0K 0:00:03 [===============================================================================================================================================================================================================================================================================================================================================================>] 100%
Run Code Online (Sandbox Code Playgroud)
我知道这一定是因为 pv 删除该行并重新绘制它的方式,但是我可以做些什么来防止它扰乱顺序吗?
stty sane是否可以清理提示符,因为有时 pv 会使终端无法使用。
谢谢
pv管道中的两个进程可以按任意顺序启动。最新的输出pv将在底线。
延迟pv你想要的底线。而不是使用子 shell pv \xe2\x80\xa6(其中表示其所有参数):\xe2\x80\xa6
( </dev/null sleep 1; exec pv \xe2\x80\xa6 )\nRun Code Online (Sandbox Code Playgroud)\n理论上,另一个pv可能仍会在延迟的之后启动,但在未完全过载的系统中,几乎可以肯定延迟的pv将最后启动。
sleep无论如何都不应该从它的标准输入中读取;</dev/null以防万一你sleep很奇怪。
我不确定某些竞争条件是否会导致出现额外的(陈旧)行。如果是这样,推迟pv(几乎肯定)应该会有所帮助。在我的测试中,当终端需要“额外”更新时,输出会被破坏。所以:
pv运行时请勿调整终端大小。clear(或按Ctrl+L)。这将清除屏幕,将提示放在顶部并在下面提供空间,而无需稍后滚动。pvs 运行时请勿打字;特别是应避免使用多个Enters (最终可能滚动文本)。pvs 以外的任何内容打印到终端pv。这适用于管道的其他部分(例如 via /dev/tty)、脚本中的异步进程(例如仅通过其 stdout)、脚本外部的进程(例如 via/dev/tty*或/dev/pts/*)。