Why isn't `tail -f … | grep -q …` quitting when it finds a match?
From StackOverflow post 'grep -q' not exiting with 'tail -f':
tail -f
will read a file and display lines later added, it will not terminate (unless a signal likeSIGTERM
is sent).grep
is not the blocking part here,tail -f
is.grep
will read from the pipe until it is closed, but it never is becausetail -f
does not quit and keep the pipe open.
A solution to your problem would probably be (not tested and very likely to perform badly):
tail -f logfile | while read line; do echo $line | grep -q 'find me to quit' && break; done
You will find more information and solutions in the linked post.
grep
does exit and the pipe goes away, although tail
keeps running. This bug report log starts with a use case very similar to yours:
I want to use
tail
andgrep
to follow a file until a particular pattern appears. Buttail
does not exit whengrep
is finished.$ echo xxx > /tmp/blabla $ tail -f /tmp/blabla |grep -m1 --line-buffered "xxx" xxx
Now
tail
still tries to read and exits only if I write again into/tmp/blabla
.Is this how it's supposed to be?
The explanation there:
tail
does exit on SIGPIPE, however it will only get the signal onwrite()
, and so you need to get more data in the file beforetail
will exit.
As far as I know, this exact mechanism is very common. Many tools exit after they try to write something to a broken pipe, it's not a bug.
Then this wish came:
It's a fair point though that
tail
, since it can hang around forever should take special steps to be responsive to the other end of the pipe going away.
And finally:
Implemented in:
https://git.sv.gnu.org/cgit/coreutils.git/commit/?id=v8.27-42-gce0415f
And indeed, when I try to reproduce your problem with tail
from GNU coreutils 8.28, I cannot. The tool exits immediately.