この行が出力を生成しないのはなぜですか? [コピー]

この行が出力を生成しないのはなぜですか? [コピー]

以下はbashで結果を生成しません。

while true ; do upower -d ; sleep 1 ; done | grep percentage | uniq

私はチェーンの最後のプログラムが何であっても、最後から2番目のプログラムが何であるかは重要ではないことを発見しました。 2番目のプログラムは常に期待される出力を生成しますが、最後のプログラムは常に結果を生成しません。

( while ... done )whileループをサブシェル(パス)にラップすることも、最後のコマンドを除くすべてをサブシェルにラップして最後のコマンドにパイプすることも重要ではないようです。

私はこの行動によって非常に混乱しました。

私の直感が教えてくれます...

...読み取りと書き込みをブロックして、チェーンに一種のI / Oデッドロックが発生し、whileループが常に出力を生成するわけではありません。しかし、一方、私はこれまで何度も何度も何度もやってきました。さらに、この場合、whileループと次のコマンドの間に問題があるのではありませんか?だから私は混乱しています。他の人が再現できない場合は、bashのバージョン情報を提供します。

すぐに明確ではない場合...

このコード行の要点は、バッテリーの割合のすべての変更を印刷しますが、新しいバッテリーレベルのみを印刷することです。ポーリングを使用します。走るだけでも同じ行動をすると思います。

upower --monitor-detail | grep percentage | uniq

しかし、これはワンタイムで、上記の方法が失敗し始めるまで、私はそれについて5秒以上考えるつもりはありませんでした。これは興味深い質問になる時です。また、モニターの詳細が後ろからポーリングされているかどうかはわかりません(そして確認するためにstraceを実行しませんでした)。

編集する:明らかに、上記のバージョンも--monitor-detail何も生成しなかったか、少なくともそうでした。ポーリング/更新の頻度が非常にまれでしたので、おそらく長い間待たなかったでしょう。知る私は元の質問を十分に待っていました)。今私はとても混乱しています。結局そのstraceを実行する必要があると思います...

答え1

を使用する必要があります。そうしないと、標準出力バッファが出力を埋めるのにgrep --line-buffered percentage長い時間がかかります。grep

答え2

Marco d'Itriの答えに加えて、すべてのツールがカスタムバッファリングをサポートしているわけではありません。実行中のツールがこれを行わない場合、またはカスタムバッファサイズで実行したい場合は、stdbufツールのバッファリング動作をオーバーライドできます。たとえば、この場合は出力をラインバッファリングします。

while true ; do upower -d ; sleep 1 ; done | stdbuf -oL grep 'percentage' | uniq

出力をバッファリング解除するよう強制します。

while true ; do upower -d ; sleep 1 ; done | stdbuf -o0 grep 'percentage' | uniq

出力を512B単位でバッファリングするように強制します。

while true ; do upower -d ; sleep 1 ; done | stdbuf -o512 grep 'percentage' | uniq

K、M、G、[...] を追加して、KB、MB、GB、[...] 単位で出力を指定できます。

while true ; do upower -d ; sleep 1 ; done | stdbuf -o512K grep 'percentage' | uniq

答え3

POSIXでは、sedriteコマンドを使用してラインバッファ出力を取得できますw

while  sleep 1
do     upower -d
done | 
sed -n /percentage/w\ /dev/fd/1 |
uniq

.../dev/fd/[num]接続をサポートするシステムで動作します。(例:ほぼすべてのLinuxシステム)

しかし、次のようにすることができます。

while  sleep 1
do     upower -d
done | 
sed '/percentage/!d;H;x
     /^\(.*\)\n\1$/d;g'

上記はこれを行う必要があります。これは小さなスクリプトuniqの機能をラップするだけです。grepsed

関連情報