次のコマンドを使用してテーマの変更を監視しようとしています。
dbus-monitor --session "interface='org.freedesktop.portal.Settings', member=SettingChanged" | grep -o "uint32 ."
これで出力は次のようになります。
uint32 0
uint32 0
uint32 1
uint32 1
uint32 0
uint32 0
uint32 1
uint32 1
この出力はテーマ遷移に由来します。何らかの理由でトピック通知が2回表示されます。それでは、uniq
次のように1つの項目だけを残すようにパイプしたいと思います。
uint32 0
uint32 1
uint32 0
uint32 1
ただし、最後に追加すると、uniq
出力は生成されなくなります。
dbus-monitor --session "interface='org.freedesktop.portal.Settings', member=SettingChanged" | grep -o "uint32 ." | uniq
からman uniq
:
INPUT(または標準入力)から隣接する一致ラインをフィルタリングし、OUTPUT(または標準出力)に書き込みます。
uniq
少なくとも最後の出力ラインは、隣接するラインを検出するためにバッファリングする必要があります。バッファリングしてパイプに沿って渡すことができない理由はありません。提案されているように行バッファリングを調整してみました。ここしかし、結果はまだ私と同じです。
dbus-monitor --session "interface='org.freedesktop.portal.Settings', member=SettingChanged" | grep -o "uint32 ." | stdbuf -oL -i0 uniq
答え1
これは多くのツールの一般的な動作であり、関数操作を介して基本的な標準Cライブラリの動作から継承されます。入力/出力ストリーム( fopen(3)
, fwrite(3)
...).これは文書化されていますsetvbuf(3)
(または使用されなくなったバリエーション)。いくつかの* nixがすべて同じことを言いました。第二SD、ソラリス、GNU/Linux...、しかしPOSIX具体的な内容がなければ、ISO / IEC 9899は難しすぎます。GNUは言う:
新しく開かれたストリームは通常完全にバッファリングされますが、1つの例外は、対話型デバイス(端末など)に接続されたストリームが最初にラインバッファリングされることです。
(返品、標準エラー通常、すべての実装でバッファリングされません。このQ&Aでは重要ではありません。 )
したがって、ほとんどのテキストフィルタリングコマンド(すべてではなく、たとえばcat
この動作はありません)の場合、パイプラインの最後のコマンドでない限り、その出力はラインバッファリングされなくなり、改行は即座に転送をトリガしません。次の注文で処理するデータ。
ここ関連コマンドではuniq
ありませんが、grep
出力が端末からビターミナルに切り替わるからです。 GNUにはgrep
この動作を変更するオプションがあります。--line-buffered
:
--line-buffered
出力時にラインバッファリングを使用します。これによりパフォーマンスが低下する可能性があります。
コマンドにアクションを選択する特定のオプションがない場合でも、コマンドを使用できます。stdbuf
setvbuf(3)
以下を使用して動作を変更します。LD_PRELOAD
器具。パイプの終わりにないコマンドのラインバッファリング動作を復元するには、コマンドの前にstdbuf -oL
。
OPの状況:
dbus-monitor --session "interface='org.freedesktop.portal.Settings', member=SettingChanged" |
grep --line-buffered -o "uint32 ." | uniq
または、このgrep
コマンドに特定のオプションがない場合:
dbus-monitor --session "interface='org.freedesktop.portal.Settings', member=SettingChanged" |
stdbuf -oL grep -o "uint32 ." | uniq
どちらの場合も、uniq
パイプラインの最後にある場合はデフォルトの動作を調整する必要はありません。
後でパイプが拡張され、もはやuniq
エンドになっていないため、ターミナルに出力されなくなった場合でも動作が変わり、同じ処理が必要です。たとえば、uniq
端末でのコマンドの個別のラインバッファリング動作は次のとおりです。
uniq
フルバッファリングに変更:
uniq | cat
ただし、次のように行バッファリングに戻すことができます。
stdbuf -oL uniq | cat