我正在阅读'高级bash脚本',在第31章中有一个问题。我想不明白。bash标准输出无法重定向到文件
tail -f /var/log/msg | grep 'error' >> logfile
为什么会出现什么可输出到日志文件?
你能给我一个解释吗? 谢谢你
我正在阅读'高级bash脚本',在第31章中有一个问题。我想不明白。bash标准输出无法重定向到文件
tail -f /var/log/msg | grep 'error' >> logfile
为什么会出现什么可输出到日志文件?
你能给我一个解释吗? 谢谢你
作为@chepner评论,grep
正在使用一个较大的缓冲区(也许4k或更多)来缓冲其标准输出。大多数标准实用程序在管道或重定向到文件时执行此操作。当直接输出到终端时,它们通常只切换到线路缓冲模式。
可以使用stdbuf
utility强制grep
做其输出的行缓冲:
tail -f /var/log/msg | stdbuf -oL grep 'error' >> logfile
由于这种效应容易观察到的示范,你可以试试下面这两个命令:
for ((i=0;;i++)); do echo $i; sleep 0.001; done | grep . | cat
和
for ((i=0;;i++)); do echo $i; sleep 0.001; done | stdbuf -oL grep . | cat
在第一个命令中,来自grep .
的输出(即,匹配所有线)缓冲进入管道到cat
。在我的缓冲区似乎是约4K。随着缓冲区被填充并刷新,您将看到chunks
中的升序数字输出。
在第二个命令中,grep
的管道输出到cat
是行缓冲的,所以你应该看到每行的终端输出,即或多或少的连续输出。
非常感谢你的回答。我想你是对的。它是'grep'扮演的角色。它只在stdout是终端时才使用缓冲区。 – ruanhao
因为/ var/log/msg尾部没有包含字符串'error'的行? 'tail -f'显示了当前正在写入的文件,'grep'只过滤了匹配的行,因此如果没有匹配的行,则不会输出任何内容。 –
@MarkReed,是的,文件'msg'中有行 – ruanhao
@ruanhao:最后10行必须有'error'文本,否则'tail -f'只会等待新日志出现。 – anubhava