Bash
如果事先只知道輸入的大小,如何跟踪管道中命令的進度?
我想使用
pv
. 這個操作的輸入大小是事先知道的,但它的輸出大小是不知道的。這迫使我把pv
操作放在管道的左邊。問題是長時間執行的命令由於緩衝而立即消耗了它的全部輸入。這有點類似於Turn off buffering in pipe問題,但在我的情況下,消耗操作很慢,而不是產生一個,並且在這種情況下,另一個問題的答案似乎都不起作用。
這是一個展示問題的簡單範例:
seq 20 | pv -l -s 20 | while read line; do sleep 1; done 20 0:00:00 [13.8k/s] [=====================================>] 100%
進度條不是每秒更新一次,而是立即跳到 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
任何解決方法的建議?謝謝!
在您的設置中,數據已通過
pv
,但仍在右側處理。您可以嘗試pv
像這樣移動到最右側:seq 20 | while read line; do sleep 1; echo ${line}; done | pv -l -s 20 > /dev/null
更新: 關於您的更新,也許最簡單的解決方案是使用命名管道和子外殼來監視進度:
#! /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