Zol*_*tan 5 shell bash pipe pv
我想使用pv
. 这个操作的输入的大小是预先知道的,但它的输出的大小不是。这迫使我将pv
操作放在管道的左侧。
问题是长时间运行的命令会因为缓冲而立即消耗其全部输入。这有点类似于关闭管道中的缓冲问题,但在我的情况下,它是消耗操作缓慢,而不是生成一个,并且在这种情况下,另一个问题的答案似乎都不起作用。
这是一个演示问题的简单示例:
seq 20 | pv -l -s 20 | while read line; do sleep 1; done
20 0:00:00 [13.8k/s] [=====================================>] 100%
Run Code Online (Sandbox Code Playgroud)
进度条不是每秒更新一次,而是立即跳转到 100% 并在处理输入所需的整个 20 秒内保持在那里。pv
如果行被逐行处理,则只能测量进度,但最后一个命令的整个输入似乎被读入缓冲区。
一个稍长一些的示例也演示了未知数量的输出行:
#! /bin/bash
limit=10
seq 20 | \
pv -l -s 20 | \
while read num
do
sleep 1
if [ $num -gt $limit ]
then
echo $num
fi
done
Run Code Online (Sandbox Code Playgroud)
有关解决方法的任何建议?谢谢!
在您的设置中,数据已通过pv
,但仍在右侧进行处理。您可以尝试pv
像这样移动到最右侧:
seq 20 | while read line; do sleep 1; echo ${line}; done | pv -l -s 20 > /dev/null
Run Code Online (Sandbox Code Playgroud)
更新: 关于您的更新,也许最简单的解决方案是使用命名管道和子外壳来监视进度:
#! /bin/bash
trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM EXIT
(rm /tmp/progress.pipe; mkfifo /tmp/progress.pipe; tail -f /tmp/progress.pipe | pv -l -s 20 > /dev/null)&
limit=10
seq 20 | \
while read num
do
sleep 1
if [ $num -gt $limit ]
then
echo $num
fi
echo $num > /tmp/progress.pipe
done
Run Code Online (Sandbox Code Playgroud)