在 CLI 程序之间传输输出时的缓冲问题
我正在尝试通过一些过滤器来跟踪 apache 错误日志。
这工作得很好:
tail -fn0 /var/log/apache2/error.log | egrep -v "PHP Notice|File does not exist"
但是输出中有一些文字“\n”,我想用实际的新行替换它,所以我通过管道输入perl:
tail -fn0 /var/log/apache2/error.log | egrep -v "PHP Notice|File does not exist" | perl -ne 's/\\n/\n/g; print"$_"'
这似乎有一些缓存问题(第一页命中没有产生任何结果,第二页命中和出来了两堆调试信息),也显得有点喜怒无常。
所以我尝试了 sed:
tail -fn0 /var/log/apache2/error.log | egrep -v "PHP Notice|File does not exist" | sed 's/\\n/\n/g'
这似乎遇到了同样的问题。
I'm trying to tail apache error logs through a few filters.
This works perfectly:
tail -fn0 /var/log/apache2/error.log | egrep -v "PHP Notice|File does not exist"
but there are some literal "\n" in the output which I want to replace with an actual new line so I pipe into perl:
tail -fn0 /var/log/apache2/error.log | egrep -v "PHP Notice|File does not exist" | perl -ne 's/\\n/\n/g; print"$_"'
This seems to have some caching issue (first page hit produces nothing, second page hit and two loads of debugging info comes out), It also seems a bit tempramental.
So I tried sed:
tail -fn0 /var/log/apache2/error.log | egrep -v "PHP Notice|File does not exist" | sed 's/\\n/\n/g'
which seems to suffer the same problem.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
正确的,当您使用大多数程序来归档或通过管道传输时,它们会缓冲输出。在某些情况下您可以控制这一点:GNU
grep
系列接受--line-buffered
选项,专门用于像这样的管道。另外,在 Perl 中您可以使用$| = 1;
达到相同的效果。 (据我所知,sed 没有任何此类选项。)缓冲的是管道开头或中间的内容,而不是结尾(正在与您的终端通信)所以它将是行缓冲的)所以你想使用
egrep --line-buffered
。Correct, when you use most programs to file or pipe they buffer output. You can control this in some cases: the GNU
grep
family accepts the--line-buffered
option, specifically for use in pipelines like this. Also, in Perl you can use$| = 1;
for the same effect. (sed
doesn't have any such option that I'm aware of.)It's the stuff at the beginning or middle of the pipeline that will be buffering, not the end (which is talking to your terminal so it will be line buffered) so you want to use
egrep --line-buffered
.看起来您可以对 sed 使用 -u ,如下所示:
它尾部日志,突出显示“joelog”,然后在有“\n”
源的地方添加换行符:
http://www-01.ibm.com/support/docview.wss ?uid=isg1IZ42070
Looks like you can use -u for sed as in:
which tails the log, highlights 'joelog', and then adds linebreaks where there are '\n'
source:
http://www-01.ibm.com/support/docview.wss?uid=isg1IZ42070