tcpdumpの出力をフィルタリングし、リアルタイムで文字列が見つかったらスクリプトを実行します。

tcpdumpの出力をフィルタリングし、リアルタイムで文字列が見つかったらスクリプトを実行します。

ポート1700で受信および送信されたパケットを表示するコマンドがあります。

tcpdump -AUq ポート 1700

パケットには文字列がありますが、rxpkほとんどのパケットには文字列はありません。出力にこの文字列が含まれている場合は、いくつかのスクリプト(LEDの点滅)を実行したいと思います。

tcpdump -AUq port 1700 | awk '/rxpk/ { print | "/path/to/blink_led 18" }'

rxpkただし、最初に見つかった場合にのみ一致するように見え、その後の発生はトリガーされません{ ... }

理由を知っている人はいますか?それとも、rxpkスクリプトを受け取ったときにスクリプトを実行する別の方法がありますか?

答え1

LEDが一度だけ点滅するのは、パイプに印刷してもパイプが開いたままであるため、呼び出しが一度だけ発生するためですblink_ledblink_led指示のために標準入力を読むと、これは問題ではありません。 stdin が読み取れない場合は終了しawkて終了します。

この問題を解決する伝統的な方法は、close()次の呼び出しが新しい呼び出しを開始するようにパイプを使用することです。

tcpdump -Alq port 1700 | awk '
  BEGIN { mypipe="/path/to/blink_led 18"; }
  /rxpk/ { print | mypipe; close(mypipe); }'

system()@heemaylが提案したように、それでも大丈夫です(blink_led標準入力をまったく読むことに興味がなければ良いかもしれません)。

目的の出力がstdioバッファで待機している場合は、一時-l停止を避けるためにstdoutをフラッシュする代わりに使用します(ファイルに書き込むときに完全なパケットフラッシュを有効にします)。-U-l-U-w

関連情報