`pv`の出力をPythonスクリプトに送り、一度に1行ずつ進行状況を出力するにはどうすればよいですか?

`pv`の出力をPythonスクリプトに送り、一度に1行ずつ進行状況を出力するにはどうすればよいですか?

私はそれを使ってtar数千の小さなファイルをすばやくコピーし、パイプを介してコピーのpv進行状況と速度を示します。

$ sudo tar c --files-from /tmp/camfilenames | 
  pv --width 40 | 
  sudo tar x -C /home/pi/test

...これはうまくいきます。出力例:

191MiB 0:00:03 [58.1MiB/s] [<=>       ]

...ターミナルで。しかし、この出力でより多くのことをしたいと思います。簡単なPythonスクリプトがあります/home/pi/screentest.py

import sys
print "start"
for line in sys.stdin:
    print "line: " + line
print "end"

テスト実行:

$ (   sudo tar c --files-from /tmp/camfilenames | 
      pv --width 40 | 
      sudo tar x -C /home/pi/test   ) | 
   python /home/pi/screentest.py

出力:

start
191MiB 0:00:03 [55.1MiB/s] [<=>       ]
end

バッファ内のすべてが返されることがわかっているので、どのように強制的にpv1行ずつ戻って、毎回バッファをフラッシュして次のように出力することができますか?

start
line: 0MiB 0:00:00 ...
line: 60MiB 0:00:01 ...
line: 120MiB 0:00:02 ...
line: 191MiB 0:00:03 ...
end

答え1

pv進行状況をstderrに出力するため、Pythonスクリプトのパイプはから印刷されませんpvend出力が停止した後に印刷されます。それはおそらくそれまでの最後の出力が終了し、スクリプトのstdinが閉じられたからです。pvtar

次のようなものが必要な場合があります。

( sudo tar c --files-from /tmp/camfilenames | 
  pv --width 40 -f | 
  sudo tar x -C /home/pi/test ) 2>&1 >/dev/null | python /home/pi/screentest.py

tarパイプのstdoutを破棄し、代わりにstderrをpythonsスクリプトに送信します。 stderrが端末でない場合は進行がないため、pv進行状況を出力するには強制する必要があります。-fpv

pvしかし、のオプションを確認したいかもしれません--format。次のようなものを使用できます。

sudo tar c --files-from /tmp/camfilenames | 
  pv --width 40 --format $'%b %t\n' | 
  sudo tar x -C /home/pi/test

同様の出力を得るために。

答え2

@muru ありがとうございます。ソリューションを試してみましたが、同時にPVが1行を継続的に更新するのではなく、新しい行を出力するように強制することが主な問題であることがわかりました。

だから私はこう書いています:

$ tail -f /home/pi/log | pv -f |& stdbuf -oL tr '\r' '\n'

うまくいったので、問題はPythonスクリプトを呼び出して各行で操作を実行する方法です。 do-whileループを使用してこれを行うことができることがわかりました。

$ tail -f /home/pi/log | pv -f |& stdbuf -oL tr '\r' '\n' | (while read -r LINE; do echo $LINE; done;)

だから私はPythonスクリプト(小さなLCDハンドラ)を使ってLCDにPVの状態を表示します。

tail -f /home/pi/log | pv -f --width 20 -i 2 |& stdbuf -oL tr '\r' '\n' | (while read -r LINE; do python /home/pi/screen.py $LINE; done;)

多くの小さなファイルをコピーしてTARスクリプトを再導入しました。

$ (sudo tar c --files-from /tmp/camfilenames | pv -f --width 20 -i 1 | sudo tar x -C /home/pi/test) |& stdbuf -oL tr '\r' '\n' | (while read -r LINE; do python /home/pi/screen.py $LINE; done;)

したがって、最終的にPVにパラメータを追加し、文字列を置き換え、PV出力をLCDに送信する前に改行を追加したとき、次のような結果が出ました。

cd /home/pi/cam \ && ( \ sudo tar c --files-from /tmp/camfilenames \ | pv -f -s $( \ du -sb /home/pi/cam \ | awk '{print $1}' \ ) --width 64 -i 5 \ | sudo tar x -C /mnt/usb \ ) \ |& stdbuf -oL tr '\r' '\n' \ | ( \ while read -r LINE; \ do LINE="${LINE// /_}"; \ LINE="${LINE//_\[/ [}"; \ LINE="${LINE//\]_/] }"; \ lcd $LINE; \ done; \ ) \ && cd /home/pi

PV出力がLCDに表示される方法は次のとおりです。 PV出力がLCDに表示される方法です。

関連情報