Monitoring a file until a string is found
The accepted answer isn't working for me, plus it's confusing and it changes the log file.
I'm using something like this:
tail -f logfile.log | while read LOGLINE
do
[[ "${LOGLINE}" == *"Server Started"* ]] && pkill -P $$ tail
done
If the log line matches the pattern, kill the tail
started by this script.
Note: if you want to also view the output on the screen, either | tee /dev/tty
or echo the line before testing in the while loop.
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
from grep
. That way, once grep
ends, the script can continue even if tail
hasn't ended yet. So this simple method will get you there:
( tail -f -n0 logfile.log & ) | grep -q "Server Started"
grep
will block until it has found the string, whereupon it will exit. By making tail
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 as grep
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 for tail
to terminate, so the pipeline exits as soon as grep
exits.
Some minor tweaks:
- The option -n0 to
tail
makes it start reading from the current last line of logfile, in case the string exists earlier in the logfile. - You might want to give
tail
-F rather than -f. It is not POSIX, but it allowstail
to work even if the log is rotated while waiting. - Option -q rather than -m1 makes
grep
quit after the first occurrence, but without printing out the trigger line. Also it is POSIX, which -m1 isn't.
If you're using Bash (at least, but it seems it's not defined by POSIX, so it may be missing in some shells), you can use the syntax
grep -m 1 "Server Started" <(tail -f logfile.log)
It works pretty much like the FIFO solutions already mentioned, but much simpler to write.