【问题标题】:grep with continuous pipe does not work带有连续管道的 grep 不起作用
【发布时间】:2017-06-28 17:28:42
【问题描述】:

(可能是“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

标签: linux bash grep pipe stdout


【解决方案1】:

我认为问题是因为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 无论如何都在整行上运行),并且应该更快一些(在这种特定情况下,性能并不重要可能性)。
【解决方案2】:

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?

【讨论】:

  • 好建议。解释一下这是做什么的,以及为什么它在这种情况下会有所作为可能会很有用。
猜你喜欢
  • 1970-01-01
  • 2014-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-14
  • 1970-01-01
相关资源
最近更新 更多