Is there some one-line way in bash/GNU tools to block until there's a string matched in a file? Ideally, with timeout. I want to avoid multi-line loop.
Update: Seems like I should have emphasize that I want the process to end when the string is matched.
I had a similar requirement and came up with the following.
The one-liner you are after is the line which starts with "timeout ...." and the rest of the code is the prep work needed to provide the one-liner with the information it will need and to clean up afterwards.
I've implemented the above into a stand alone script which can be used to run a command wait for its log file to have the required pattern, with a timeout.
Available here: run_and_wait.sh
wait for file to appear
wait for string to apper in file
https://superuser.com/a/743693/129669
or, if you want to suppress the output of non-matching lines:
A simple-minded way to add a timeout is to do:
(Suppress the errors from the kill so that if the process terminates before the time expires, you don't get the "No such process" warning). Note that this is not at all robust, since it is possible that cmd will terminate and the pid count will wrap around and some other command will have that pid by the time the timer expires.
Thanks both for answers, but the important part was that the process blocks until found, then ends. I found this:
-q
is not much portable, but I will only use Red Hat Enterprise Linux so it's ok. And with timeout:Take a look at the
--max-count
option:It will exit after the first line that matches
PATTERN
.EDIT: take note of @Karoly's comment below. If the
file.log
velocity is slow, it's possible that thegrep
process will block until additional content is added to the file after the matching line.will print the matching line, but it will not exit until additional content is appended to the file (even if it doesn't have a newline yet):
In some cases (such as a high-velocity log file), this isn't a big deal, because new content is probably going to be added to the file soon anyway.
Also note that this behavior does not happen when reading from a console as stdin, so it appears to be a difference in the way
grep
reads from a pipe:Will post snip with async timeout
For now: How to include a timer in Bash Scripting?
The linked answer defines a 'run_or_timeout' function that does what you are looking for in a very bash-savvy way