tail -1000f 不显示与 tail -1000 相同的输出

tail -1000f 不显示与 tail -1000 相同的输出

我正在尝试执行

tail -100000f MXMLExchangeMonitoring_Mx3.log | egrep "INTENTO.*Workflow" | cut -d ":" -f "3" | cut -c 3,4,5,6 | awk '{if($1>20)print$1}' 

我什么也没得到。

但与

tail -100000 MXMLExchangeMonitoring_Mx3.log | egrep "INTENTO.*Workflow" | cut -d ":" -f "3" | cut -c 3,4,5,6 | awk '{if($1>20)print$1}'

我得到了预期的结果:

212
45
29
463
544
556
543
1115
830
802
119
95
33
31
194
170
127
97

我需要它-f,以便我可以读取文件中出现的大于 20 的新数字。

减少行数也是一种选择,我可以从少量开始,例如-100。

tail -f作品适用于:

tail -100000f MXMLExchangeMonitoring_Mx3.log | egrep "INTENTO.*Workflow" | cut -d ":" -f "3"

答案1

命令与标准输出不是终端(这里是管道之前的命令)将具有 stdio C 函数(例如fwrite())进行块(又名完整)缓冲。这是行为的一些描述setvbuf(3)(这是标准 C 和POSIX函数,但描述取自 GNU 变体。POSIX可能表明确切的行为是实现定义的):

通常情况下所有文件都是块缓冲的。如果一个流引用了一个 终端(如标准输出通常是这样),它是行缓冲的。标准错误流标准错误默认情况下始终不缓冲。

除最后一个管道之外的一系列管道中的所有命令都可能受到影响:它们获得块缓冲其输出的正常行为。


这是至少在 Linux 和 FreeBSD 上有效的方法。

  • 某些命令 ( tail) 的行为与此“预期”相同

    没事做。

  • 其他 ( grep) 对此有选项

    对于 GNU 和 *BSD(甚至 Mac OS X),grep有一个内置--line-buffered选项可以更改其行为

  • 其他 ( cut) 则不然。有解决方法,可能是系统特定的

    在 GNU 以及 FreeBSD 系统(但显然不是其他 *BSD 变体)上有一个 libc 包装工具stdbuf目的是:

    例子

    tail -f access.log | stdbuf -oL cut -d ' ' -f1 | uniq
    

    这将立即显示 access.log 中的唯一条目

  • awk位于管道的末尾并输出到终端,因此不受影响(即:它已经是行缓冲的)

    如果稍后需要,此工具包含fflush()用于达到相同效果的命令。

所有这些动态链接的工具都应该支持使用,stdbuf -o L即使不使用它们的某些专用功能,但最好不要使用 libc 包装器(如果可能的话)。

考虑到所有这些,并且stdbuf安装后,此修改后的行应该按预期运行(我将其分成多行以使其更易于阅读):

tail -100000f MXMLExchangeMonitoring_Mx3.log |
    egrep --line-buffered "INTENTO.*Workflow" |
    stdbuf -o L cut -d ":" -f "3" |
    stdbuf -o L cut -c 3,4,5,6 |
    awk '{if($1>20)print$1}' 

在一些更简单的过滤情况下,只需重新排序命令以仅保留其行为不易更改的命令(如最后一个那样)就足够了。但如果没有stdbuf,即使有两个cut正在酝酿中也无法解决问题。

相关内容