Linux – Why isn’t `tail -f … | grep -q …` quitting when it finds a match

greplinuxtail

I'm doing a pretty standard tail + grep:

tail -f some_log_file.txt | grep -q known-string

If I run the command without the -q:

tail -f some_log_file.txt | grep known-string

I see output:

[Tue Feb 12 11:32:45 2019] known-string.

so I know the grep is matching. However when I add -q the grep command doesn't exit, it just hangs there waiting for more output … even though the man page says it will "Exit immediately with zero status if any match is found":

   -q, --quiet, --silent
          Quiet;  do  not  write  anything  to  standard   output.    Exit
          immediately  with  zero status if any match is found, even if an
          error was detected.  Also see the -s or --no-messages option.

Can anyone explain why -q isn't causing my grep to exit? I'm trying to chain a && beep to the end so the grep beeps when a match is found, but unless I can make it exit that won't work.

Best Answer

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 like SIGTERM 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 because tail -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.

Related Question