web-dev-qa-db-ja.com

プログレスバーを含む出力をリアルタイムでgrepする方法は?

大量のゴミを印刷するツール(openocd)を使用しています。次に、基本的なプログレスバーで単純なドットをゆっくりと印刷し、次にゴミを印刷します。

この出力をgrepでフィルタリングして、プログレスバーのある行のみをリアルタイムで表示したいと思います(つまり、openocdによって出力された各ドットはすぐに端末に出力されます):

openocd <args> |& grep '^\.'

問題は、grepが(せいぜい)行バッファリングされているため、終了するまで進行状況バーが表示されないことです。

grepを使用するにはどうすればよいですか、またはこれを実現するための標準的な代替手段はありますか? openocd構成を使用する方法がある場合、これは便利ですが、より一般的な解決策を使用します。

4
calandoa

これは一種のハック/異常な答えです。これは、あまりクリーンでない方法で可能性が高いという事実です。


grep自体は、改行文字が検出された場合にのみ出力を出力するようです。プログレスバーは、更新時に改行文字を導入しない可能性が高いため、問題が発生します。

straceは、コマンドが呼び出しているシステムコールを表示するために使用されるツールです。これには、メモリ/ストレージへの読み取りや書き込み、ファイル記述子の開閉などが含まれます。


straceを使用すると、プロセスがアクセスしているものを表示できます。パイプの場合、stoutgrepに渡されているため、straceを使用すると、grepにフィードされているテキストを表示できます。 straceには、pipedコマンドからの出力が定期的に送信され、その出力をスニッフィングして表示できます。私はrsync --progressでテストしていましたが、これは同様のシナリオに遭遇したようです。 ##%grepを使用しました。これは、rsyncが進行状況を表示するために使用するためです。

rsync --progress file1 file2 | strace -e trace=read grep "[0-9]*%"

このコマンドを実行すると、straceにNiceの出力がないことがわかりますが、stracereadからrsyncをいくつかキャッチしましたが、grepは通常writeではなく、readsの0%、21%、45を示しています%、68%、91%、100%は、ほぼ毎秒更新されているようです(おそらく、rsyncが進行状況を更新する頻度に基づいています)。

そのため、同じgrepを再度呼び出すことで、strace出力をgrepできますが、これはあまり良いことではありません。

rsync --progress file1 file2 | strace -e trace=read grep "[0-9]*%" 2>&1 > /dev/null | grep -o "[0-9]*%"

stracestderrに出力されるため、2>&1は重要です。 > /dev/nullstdout/dev/nullにリダイレクトして、最初のgrepの出力が報告されないようにします。これの最終結果は次の出力でした:

0%
21%
45%
68%
91%
100%

grepを交換する必要がありますが、これでうまくいくようです。きれいではありませんが、機能し、grepの制限を回避します。 grep -fのように機能するtail -fは便利だと思われます(grep -fはすでに使用されています)。

最初のgrepは、stracereadingになるテキストをフィルタリングするだけです。これは、straces read呼び出しに一致する行のみがリストされるためですが、straceがそれを監視できるようにテキストを移動するための何かも必要です。

3
Centimane