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

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

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

tcpdump -AUq ポート 1700

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

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

しかし、最初に見つかった場合にのみ一致するようで、その後の出現では-partはrxpkトリガーされません。{ ... }

rxpk理由が分かる人はいますか? または、受信時にスクリプトを実行する別の方法はありますか?

答え1

LED が 1 回しか点滅しない理由は、パイプに印刷する場合、パイプは開いたままなので、 の呼び出しは 1 回だけだからですblink_ledblink_ledが命令のために stdin を読み取る場合、これは問題にはなりません。 が stdin の読み取りに失敗して終了した場合、 もawk終了します。

これを回避する従来の方法はclose()パイプを使用して、次の呼び出しで新しい呼び出しを開始することです。

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

system()blink_led@heemayl が提案しているように、これも問題ありません ( stdin の読み取りにまったく興味がない場合は、おそらくこれの方が良いでしょう)。

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

関連情報