I am using tail -f to monitor a log file that is being actively written to. When a certain string is written to the log file, I want to quit the monitoring, and continue with the rest of my script.
Currently I am using:
tail -f logfile.log | grep -m 1 "Server Started"
When the string is found, grep quits as expected, but I need to find a way to make the tail command quit too so that the script can continue.
Best Answer
A simple POSIX one-liner
Here is a simple one-liner. It doesn't need bash-specific or non-POSIX tricks, or even a named pipe. All you really need is to decouple the termination of
tail
fromgrep
. That way, oncegrep
ends, the script can continue even iftail
hasn't ended yet. So this simple method will get you there:grep
will block until it has found the string, whereupon it will exit. By makingtail
run from it's own sub-shell, we can place it in the background so it runs independently. Meanwhile, the main shell is free to continue execution of the script as soon asgrep
exits.tail
will linger in its sub-shell until the next line has been written to the logfile, and then exit (possibly even after the main script has terminated). The main point is that the pipeline no longer waits fortail
to terminate, so the pipeline exits as soon asgrep
exits.Some minor tweaks:
tail
makes it start reading from the current last line of logfile, in case the string exists earlier in the logfile.tail
-F rather than -f. It is not POSIX, but it allowstail
to work even if the log is rotated while waiting.grep
quit after the first occurrence, but without printing out the trigger line. Also it is POSIX, which -m1 isn't.