Using tail -n0 -f
piped to grep
is indeed a nice solution, and indeed the first process in the pipe will die when it tries to output to a dead grep process.
But if you're hunting for text that appears near to the last current output of the tail, then grep will already have read the whole input from the tail (in one block) and therefore there won't be any more text output in the log that needs sending down the pipe as grep already read it before it quit (or maybe it was already in the pipe buffer) - at least this is my understanding.
Using -m1
option on grep looks like it'd do exactly what you want and leave the input immediately after the line it matched, but it didn't seem to make a difference or help me in my search for similar functionality. I suspect the pipe buffer still holds all the text output from tail, or some other reason for tail not to have anything left to output. You wanted this post-grep-match text still left to be output next, because its what would kill your tail when it tried (still risky - what happens if its the last line for some reason?), and return control to the calling script.
I found one way round it is to output anything into the end of the log file once the grep has quit; ie.
tail -f logfile | ( grep -q ; echo >> logfile)
I have a theory that (if my guess is right) you could force the pipe to be less buffered to make it work without this, or maybe that adding a huponexit
setting command to the appropriate pipe component - i.e. in (probably curly) brackets would help; but I didn't care about appending a blank line to the logfile and it worked ok and its only a smaller test script (so not a long lived logfile that needs to stick to a format for other processing).
shopt -s huponexit
would be useful but for the subshell-ness of it.
PS my first post here, would liked to do it as a comment to existing answer rather than re-iterate stuff, but I don't think I can now.
read -t 30 line
will wait thirty seconds after each line that's been read, and then, if there's nothing more to read, returns false (breaking out of the loop) – Pyrology