无法使用管道处理标准输出

无法使用管道处理标准输出

我在 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 命令

运行命令而不是交互式 shell。这使得脚本可以轻松捕获当标准输出不是 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

您应该能够实时看到台词。

相关内容