如何通过管道从`tail -f`读取一行,然后终止?

jon*_*rry 9 unix bash

我想通过对文件的更改进行跟踪tail -f,然后grep在终止之前打印出与命令匹配的第一行。什么是最简单的方法来做到这一点?到目前为止,我一直在尝试这样的事情:

tail -f foo.log | grep 'bar' | head -1
Run Code Online (Sandbox Code Playgroud)

然而,管道只是挂起,大概是由于缓冲。我也试过

tail -f foo.log | grep --line-buffered 'bar' | head -1
Run Code Online (Sandbox Code Playgroud)

这会打印出该行,但除非我点击 ^C,否则该过程不会终止,大概是因为需要第二行输入来终止head -1。解决这个问题的最佳方法是什么?

小智 12

tail -f foo.log | grep -m 1 bar
Run Code Online (Sandbox Code Playgroud)

如果文件 foo.log 很少写入,您可以执行以下操作:

grep -m 1 bar <( tail -f foo.log )
Run Code Online (Sandbox Code Playgroud)

应该注意的是,tail -f 将保持在后台,直到它有另一行输出。如果这需要很长时间,则可能会出现问题。这种情况下的解决办法是:

grep -m 1 bar <( exec tail -f foo.log ); kill $! 2> /dev/null
Run Code Online (Sandbox Code Playgroud)

kill 将终止剩余的 tail -f 进程,并且我们隐藏错误,因为在调用 kill 时尾部可能会消失。