how to proceed once a file containing something in shell
I am writing some BASH shell script that will continuously chec开发者_如何学Pythonk a file to see if the file already contains "Completed!" before proceeding. (Of course, assume the file is being updated and will eventually contain the phrase "Completed!")
I am not sure how to do this. Thank you for your help.
You can do something like:
while ! grep -q -e 'Completed!' file ; do
sleep 1 # Or some other number of seconds
done
# Here the file contains completed
Amongst the standard utilities, tail
has an option to keep reading from a file: tail -f
. So filter the output of tail -f
.
<some_file tail -f -n +1 | grep 'Completed!' | head -n 1 >/dev/null
There may be a delay due to buffering. You can at least reduce the delay by using fewer tools in the pipeline. In fact, some implementations of tail
never buffer when you do tail -f
, so the following snippet will return as soon as Completed!
is written to the file.
<some_file tail -f -n +1 | sed -e '/Completed!/ q'
This assumes that the file is being appended to by some other tool. If the file is overwritten by the data-producing program after you start tail
, this solution won't work. You can search the file periodically. On some systems you can call a notification mechanism to know whenever the file changes, e.g. with inotifywait
under Linux.
I've done this in Kornshell:
tail -f somefile | while read line
do
echo $line
[[ $line == *Completed!* ]] && break
done
Note no quotes around the *Completed!* string. This allows the double square brackets to do glob pattern matching instead of string matching.
This seems to work in BASH too. However, the line with the Completed
must end in a NL. Otherwise, it'll take an extra line before it breaks the loop.
You can use grep
too:
tail -f somefile | while read line
do
echo $line
grep -iq "Completed!" && break
done
The -q
parameter means quiet. If your grep
doesn't take the -q
parameter, you might have to pipe it to /dev/null
. The -i
is ignore case. Whether you want to do that is up to you.
The advantage is that you aren't doing any processing unless there's a line to read. Using sleep
may mean you miss the line, or that you're processing when no line has been added to the file.
Using grep
in a pipe you may turn on line buffering mode by adding the --line-buffered
option!
精彩评论