以下は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では、sed
riteコマンドを使用してラインバッファ出力を取得できます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
の機能をラップするだけです。grep
sed