pv
を使用して遅い操作の進行状況を追跡したいと思います。この操作の入力のサイズは事前にわかっていますが、出力のサイズはわかりません。これにより、パイプ内の操作の左側にpv
を配置する必要がありました。
問題は、長時間実行されるコマンドがバッファリングのために入力全体をすぐに消費することです。これは パイプのバッファリングをオフにする の質問にいくぶん似ていますが、私の場合、遅いのは消費操作であり、生成する操作ではなく、他の質問に対する答えはどれも機能しないようですこの場合。
これは、問題を示す簡単な例です。
seq 20 | pv -l -s 20 | while read line; do sleep 1; done
20 0:00:00 [13.8k/s] [=====================================>] 100%
プログレスバーは毎秒更新されるのではなく、すぐに100%にジャンプし、入力の処理にかかる20秒間ずっとそこにとどまります。 pv
は、行が1つずつ処理された場合にのみ進行状況を測定できましたが、最後のコマンドの入力全体がバッファーに読み込まれたようです。
不明な数の出力行も示す、やや長い例:
#! /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
pdate:更新に関して、おそらく最も簡単な解決策は、名前付きパイプとサブシェルを使用して進行状況を監視することです。
#! /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