Bash

如果事先只知道輸入的大小,如何跟踪管道中命令的進度?

  • October 22, 2016

我想使用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

引用自:https://unix.stackexchange.com/questions/318173