带有连续管道的 grep 不起作用
Posted
技术标签:
【中文标题】带有连续管道的 grep 不起作用【英文标题】:grep with continuous pipe does not work 【发布时间】:2017-02-10 11:20:24 【问题描述】:(可能是“tcpflow”问题)
我写了一个脚本来监控http流量,我安装tcpflow
,然后grep
它工作(你应该发出一个http请求,例如curl www.163.com
)
sudo tcpflow -p -c -i eth0 port 80 2>/dev/null | grep '^Host: '
这样输出(连续)
Host: config.getsync.com
Host: i.stack.imgur.com
Host: www.gravatar.com
Host: www.gravatar.com
但我不能继续使用管道
不起作用(无输出)
sudo tcpflow -p -c -i eth0 port 80 2>/dev/null | grep '^Host: ' | cut -b 7-
不起作用(无输出)
sudo tcpflow -p -c -i eth0 port 80 2>/dev/null | grep '^Host: ' | grep H
当我用cat foo.txt
替换sudo tcpflow
时,它可以工作:
cat foo.txt | grep '^Host: ' | grep H
那么管道、grep 或 tcpflow 有什么问题?
更新:
这是我的最终脚本:https://github.com/zhengkai/config/blob/master/script/monitor_outgoing_http.sh
【问题讨论】:
sudo tcpflow -p -c -i eth0 port 80 2>/dev/null | grep '^Host: '
的输出是什么?
@Inian 现在我添加它有问题
它是如何失败的?没有输出?
@ZhengKai:是不是不断增加的数据流?
@linuxfan 不适用于 ToT
【参考方案1】:
到grep
连续流使用--line-buffered
选项:
sudo tcpflow -p -c -i eth0 port 80 2> /dev/null | grep --line-buffered '^Host'
--行缓冲
在输出上使用行缓冲。这可能会导致性能下降。
关于缓冲输出的一些思考(也提到了stdbuf
工具):
Pipes, how do data flow in a pipeline?
【讨论】:
好建议。解释一下这是做什么的,以及为什么它在这种情况下会有所作为可能会很有用。【参考方案2】:我认为问题是因为stdio buffering
,你需要在调用grep
之前使用GNU stdbuf
,
sudo tcpflow -p -c -i eth0 port 80 2>/dev/null | stdbuf -o0 grep '^Host: '
使用-o0
,它基本上意味着来自tcpflow
的输出(stdout
)流将是无缓冲的。默认行为是在发送到管道中的下一个命令之前自动将数据缓冲到 40961 字节块中,这是使用 stdbuf
1. 参考这个nice detail进入主题。
【讨论】:
行缓冲 (-oL
) 在这种情况下同样好(grep 无论如何都在整行上运行),并且应该更快一些(在这种特定情况下,性能并不重要可能性)。以上是关于带有连续管道的 grep 不起作用的主要内容,如果未能解决你的问题,请参考以下文章