
私はツール ( openocd
) を使用していますが、大量のゴミを印刷し、次に基本的な進行状況バーがゆっくりと単純なドットを印刷し、その後再びゴミを印刷します。
この出力を でフィルタリングして、grep
進行状況バーのある行のみをリアルタイムで表示します (つまり、 によって出力される各ドットがopenocd
すぐにターミナルに印刷されます)。
openocd <args> |& grep '^\.'
問題は、grep
行バッファリングされる (せいぜい) ため、完了するまで進行状況バーが表示されないことです。
ではどうすればよいですgrep
か、またはこれを実現するための標準的な代替手段はありますか? 構成による方法があればopenocd
便利ですが、より一般的なソリューションを希望します。
答え1
これは一種のハッキー/珍しい答えですが、実際には、これはあまりきれいではない方法で可能である可能性が高いということです。
grep
それ自体は改行文字に遭遇したときにのみ出力を印刷するようです。進行状況バーは更新時に改行文字を導入しない可能性が高いため、問題が発生します。
strace
コマンドが呼び出しているシステム コールを表示するために使用されるツールです。これには、メモリ/ストレージへの読み取りや書き込み、ファイル記述子のオープン/クローズなどが含まれます。
を使用すると、プロセスがアクセスしているものを表示できます。パイプが に渡されるstrace
場合、 を使用すると、に送られるテキストを表示できます。には、パイプされたコマンドからの出力が定期的に送信され、その出力をスニッフィングして表示できます。 でテストしていましたが、同様のシナリオに遭遇したようです。 は進行状況を表示するためにを使用するため、を使用しました。stout
grep
strace
grep
strace
rsync --progress
grep
##%
rsync
rsync --progress file1 file2 | strace -e trace=read grep "[0-9]*%"
このコマンドを実行すると、strace
出力は適切ではありませんが、私が使用したときは、通常は取得されないからstrace
いくつかの が取得され、0%、21%、45%、68%、91%、100% の が表示され、約 1 秒ごとに更新されているように見えました (おそらく、進行状況の更新頻度に基づいています)。read
rsync
grep
write
read
rsync
そのため、同じものを再度呼び出すと、あまり見栄えの良くない出力grep
が得られます。strace
grep
rsync --progress file1 file2 | strace -e trace=read grep "[0-9]*%" 2>&1 > /dev/null | grep -o "[0-9]*%"
は に印刷される2>&1
ため重要です。はにリダイレクトして、最初の の出力が報告されるのを防ぎます。この最終結果は次の出力でした。strace
stderr
> /dev/null
stdout
/dev/null
grep
0%
21%
45%
68%
91%
100%
を交換する必要がありますgrep
が、うまくいくようです。見た目は良くありませんが、機能し、 の制限を回避しますgrep
。grep -f
のように機能する がtail -f
便利そうです ( がすでに使用されていることは知っていますgrep -f
)。
最初の目的は、一致する行のみがs呼び出しでリストされるため、実行されるテキストgrep
をフィルタリングすることだけですが、テキストが移動するのを監視するための何かも必要です。strace
read
strace
read
strace
答え2
最終的な答えは非常に複雑なので、Centimane の答えについて詳しく説明します。
すでにかなりハッキーでしたが、今では本当にひどいものになっています。
make flash \
|& strace -e trace=read grep -e "^\." -e rror \
|& stdbuf -o0 sed -ne 's/^.*"\.".*/\./p;/rror/p' \
| stdbuf -o0 tr -d '\n' \
; echo
したがって、make flash
上記は呼び出しですopenocd
。
strace
上記で説明した Centimane のハックを使用しています。
sed
read(0, ".", xxx)
行を単一の.
;に置き換えます。
tr
すべてを.
1 行に保持し、最後のエコーで EOL のみを配置します。
それに加えて、sed
と がtr
呼び出されstdbuf -o0
、stdout バッファ サイズが 0 に設定されます (EOL が削除されるため)。また、は、エラーの場合に何らかのゴミを出力するためにgrep/sed
も使用されます。(e)rror
私はこの肥大化を最小限にしようと試みましたが、これ以上のことはできませんでした。
また、私は zsh/Ubuntu 14.04 を使用していますが、これが他の Unix でも動作するかどうかはわかりません。