私はFIFOでtsharkを実行していますが、以下はtsharkの出力を出力するループの裸の例です来たときに:
tshark -i $fifo | while read line; do
echo $line
done
Tsharkにフィルターを追加すると問題が発生します。この例では、tsharkが終了した後にのみすべての$line
を出力します(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が終了するとすべてが再度印刷されるため、お得ではありません。
tshark
バージョンには-l
(ほぼ)ラインバッファ出力のオプション。
Coreutilsのstdbuf
で動作させることができました。パイプの後のすべてのコマンドでは、バッファーも調整する必要があることに注意してください。
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.
一部のユーティリティはisatty()を呼び出して、出力が端末であるかどうかを判断し、それに応じて動作を調整します。 gzip
はこの良い例です。
script(1)
で実行してみてください。
-c、-commandコマンド
対話型シェルではなくコマンドを実行します。これにより、スクリプトは、stdoutが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
線がライブで出てくるのを見ることができるはずです。