多光伏订单

多光伏订单

我在 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

我期望的是第一个 pv 总是首先显示,第二个总是第二个。

就像这个例子的输出:

$ ./fancy_pv.sh
  Lookups: 1.00k / 1.0K 0:00:03 [===============================================================================================================================================================================================================================================================================================================================================================>] 100%            
  Deletes:  189  / 1.0K

但事实并非如此,有时他们交换位置,我看到这样的事情:

$ ./fancy_pv.sh
  Deletes:  199  / 1.0K
  Lookups: 1.00k / 1.0K 0:00:03 [===============================================================================================================================================================================================================================================================================================================================================================>] 100%            

有时我也会看到这样的事情:

$ ./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%            

我知道这一定是因为 pv 删除该行并重新绘制它的方式,但是我可以做些什么来防止它扰乱顺序吗?

stty sane是否可以清理提示符,因为有时 pv 会使终端无法使用。

谢谢

答案1

pv管道中的两个进程可以按任意顺序启动。最新的输出pv将在底线。

延迟pv你想要的底线。而不是使用子 shell pv …(其中表示其所有参数):

( </dev/null sleep 1; exec pv … )

理论上,另一个pv可能仍然在延迟的之后启动,但在不完全过载的系统中,几乎可以肯定延迟的pv将最后启动。

sleep无论如何都不应该从它的标准输入中读取;</dev/null以防万一你sleep很奇怪。

我不确定某些竞争条件是否会导致出现额外的(陈旧)行。如果是这样,推迟pv(几乎肯定)应该会有所帮助。在我的测试中,当终端需要“额外”更新时,输出会被破坏。所以:

  • pv运行时请勿调整终端大小。
  • 避免滚动:
    • 在运行脚本之前,调用clear(或按Ctrl+ L)。这将清除屏幕,将提示放在顶部并在下面提供空间,而无需稍后滚动。
    • pvs 运行时请勿打字;特别是应避免使用多个Enters (最终可能滚动文本)。
    • 一般来说,在 s 完成之前,不要让除pvs 以外的任何内容打印到终端pv。这适用于管道的其他部分(例如 via /dev/tty)、脚本中的异步进程(例如仅通过其 stdout)、脚本外部的进程(例如 via/dev/tty*/dev/pts/*)。

相关内容