遅い作業の進行状況を追跡するために使用したいと思います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
回避策に関する提案はありますか?ありがとうございます!
答え1
設定ではデータが渡されますが、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