tail-pipe-awk脚本,在Centos上很好,但在Ubuntu上很奇怪

我在CentOS上编写了一个脚本,现在我正试图在Ubuntu上运行它,它的行为出乎意料。 这里有一些像我在bash下运行的脚本:

sudo tail -F /var/opt/my-application/log/my-application.log | awk ' BEGIN { ORS=" " } { if ($8 ~ /MATCH-TEXT/) { # do a whole bunch of stuff here # like look in /proc and calculate CPU and interface stats }; }; } ' 

以前,当我在日志的$ 8字段中出现一行MATCH-TEXT时,所有的“做了一大堆东西”(脚本的肉)会发生,我会看到输出。 我的应用程序每秒产生一次MATCH-TEXT行(有时更多,有时更less),这个脚本的输出也是如此。

但是现在,当我启动这个脚本的时候,我很久没有输出了,然后我得到了30行输出。 看起来脚本正在对接收到的日志行进行排队,然后快速执行几次,因为CPU和界面上的计算对于“自一秒钟之前的一小部分时间”而不是“自一秒钟以前”起就是正确的。

更奇怪的是,将awk命令的所有内容注释掉,将其replace为“print $ 0”(将整个脚本转换为令人尴尬的grep命令)会产生相同的结果。 所以我相信这是系统执行脚本的方式,而不是脚本本身。

与此同时,在另一个窗口中,一个普通的“sudo tail -F my-application.log | grep MATCH-TEXT”每秒钟都会得到输出(就像预期的那样)。

任何想法发生了什么? 任何暗示,我应该开始寻找是什么导致这种排队行为?

如果这不是由于tail的差异,那么我同意Hauke Laging的说法,这可能是一个缓冲问题。 要刷新awk的输出缓冲区,请尝试在打印语句之后添加fflush() ,就像我在以下testing代码中所做的那样:

 tail -F /var/log/apache2/access_log | awk '{ if ($8 ~ /MATCH-TEXT/) { print $0; fflush(); }}' 

mawk -W交互式修复了Debian Wheezy上的问题。

  tail -f data.log | grep --line-buffered '$DataString' | mawk -W interactive -F "," '{print "var2", $2, "var4", $4}' 

在研究了所有的答案之后,尝试了fflush和stdbuf(之前我不知道,谢谢),我发现答案分为两部分:

1)CentOS使用gawk,Ubuntu使用mawk(默认)。

我没有评论哪个更好,或者为什么使用这个决定,两个分布是不同的。 (:

2)mawk有一个命令行选项“交互式”,从手册页:

  -W interactive sets unbuffered writes to stdout and line buffered reads from stdin. Records from stdin are lines regardless of the value of RS. 

我只能假设这是因为缓冲是在awk内,而不是脚本本身,这使得stdbuf没有这个工作。