带有连续管道的 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 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

为啥在与数组中的字段匹配时,mongoDB聚合中的查找中的管道不起作用?

角度:limitTo 管道不起作用

日期范围在聚合管道中不起作用,但在 find() 中起作用

多管道C程序不起作用

多次分叉后写入管道不起作用

为 onehotencoded 变量创建管道不起作用