web-dev-qa-db-ja.com

`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 script /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

pvがすべてを1つのバッファーに返すことを理解しているので、強制的に1行ずつ返して、毎回バッファーをフラッシュして次のようなものを出力する方法。

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

pvは進行状況をstderrに出力するため、pythonスクリプトはpvから何も取得しませんでした。endの出力が停止した後、おそらく最後のpvが終了したため、tarが出力されました。スクリプトのstdinは閉じられていました。

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

( 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は進行しないため、pvからの進行状況出力を-fで強制する必要があることに注意してください。

ただし、pv--formatオプションを調べることをお勧めします。次のようなものを使用できます。

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

同様の出力を取得します。

1
muru

@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スクリプト(little 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でどのように見えるかです: This is how PV output looks on LCD

1
marcinpl87