私はfifoでtsharkを実行しています。以下は、tshark出力を印刷するループの簡単な例です。それだけです。:
tshark -i $fifo | while read line; do
echo $line
done
tsharkにフィルタを追加すると問題が発生します。この例では、$line
tsharkが終了した後にのみすべてのsを印刷します(IPアドレスは非表示)。
tshark -i $fifo -T fields -e text -R '
ip.src == **.**.***.** &&
http.response.code == 200 &&
http.content_encoding == "gzip" &&
http.content_type contains "text/html"
' | while read line; do
echo $line
done
別の形式を試しましたが、運がありません。
while read line; do
echo $line
done < <(tshark ...)
while read line; do
echo $line
done <<<"$(tshark ...)"
grepもtsharkが終了した後にのみ、次の行を印刷します。
tshark ... | grep .
パイプなしでtsharkを実行してみたところ、線が現れるように正しく印刷されました。 tsharkが終了した後にのみパイプラインの背後にあるコマンドが送信されるのはなぜですか?
追加の詳細: | tee
うまくいきますが、tsharkが終了するとすべてを再印刷するので、良い取引ではありません。
答え1
stdbuf
coreutilsで利用可能です。パイプラインの後の各コマンドもバッファを調整する必要があります。
stdbuf -o 0 tshark -i $fifo -T fields -e text -R '
ip.src == **.**.***.** &&
http.response.code == 200 &&
http.content_encoding == "gzip" &&
http.content_type contains "text/html"
' |
stdbuf -o 0 sed 's/\\r\\n,\?/\n/g; s/\\t/\t/g' |
マニュアルページから:
`stdbuf': Run a command with modified I/O stream buffering
(...)
`-o MODE'
`--output=MODE'
Adjust the standard output stream buffering.
答え2
バージョンに(ほぼ)ラインバッファ出力オプションがtshark
あることを確認してください。-l
答え3
一部のユーティリティは出力が端末であることを確認し、それに応じて動作を調整するためにisatty()を呼び出します。gzip
良い例です。
次のコマンドを使用して実行してみてくださいscript(1)
。
-c, --command コマンド
対話型シェルの代わりにコマンドを実行してください。これにより、スクリプトは標準出力がttyでないときに動作が異なるプログラムの出力を簡単にキャプチャできます。
次のように実行すると:
script -c tshark -i $fifo -T fields -e text -R '
ip.src == **.**.***.** &&
http.response.code == 200 &&
http.content_encoding == "gzip" &&
http.content_type contains "text/html"
' | while read line; do
echo $line
done
リアルタイムでラインを見ることができるはずです。