为什么它无法在 Linux 中使用“tail -fn0 output.log | grep error >> error.log”

Why would it failed to use " tail -fn0 output.log | grep error >> error.log " in Linux

我想写一个 shell 脚本来持续监视我的日志

一些我的写作方式

 tail -fn0 output.log | grep error >> error.log

不会将包含“错误”的日志输出到 error.log

如果我写

 tail -fn0 output.log | \
    while read line ; do
    echo "$line" | grep error >>error.log
    done

它会完美地工作

我就是想知道为什么我不能这样写

tail -fn0 output.log | grep error >> error.log

它是如何工作的?

你需要使用grep --line-buffered:

tail -f output.log | grep --line-buffered error >> error.log

要重现解决方案,请使用此示例:

for i in `seq 1 10` ; do echo "error $i"; sleep 10; done > output.log &
rm error.log
tail -f output.log | grep --line-buffered error >> error.log &
head output.log error.log

输出:

head output.log error.log
==> output.log <==
error 1
error 2
error 3
...

==> error.log <==
error 1
error 2
error 3
...

另请参见:

grep manual

--line-buffered
Use line buffering for standard output, regardless of output device. By default, standard output is line buffered for interactive devices, and is fully buffered otherwise. With full buffering, the output buffer is flushed when full; with line buffering, the buffer is also flushed after every output line. The buffer size is system dependent.