Is it possible to write a script that does not proceed till a given line appears in a particular file?
For example I want to do something like this:
CANARY_LINE='Server started'
FILE='/var/logs/deployment.log'
echo 'Waiting for server to start'
.... watch $FILE for $CANARY_LINE ...
echo 'Server started'
Basically, a shell script that watches a file for line (or regex).
We have to be careful with loops.
For example if you want to check for a file to start an algorithm you've probably have to do something like that:
FILE_TO_CHECK="/var/logs/deployment.log"
LINE_TO_CONTAIN="Server started"
SLEEP_TIME=10
while [ $(cat FILE_TO_CHECK | grep "${LINE_TO_CONTAIN}") ]
do
sleep ${SLEEP_TIME}
done
# Start your algorithm here
But, in order to prevent an infinite loop you should add some bound:
FILE_TO_CHECK="/var/logs/deployment.log"
LINE_TO_CONTAIN="Server started"
SLEEP_TIME=10
COUNT=0
MAX=10
while [ $(cat FILE_TO_CHECK | grep "${LINE_TO_CONTAIN}") -a ${COUNT} -lt ${MAX} ]
do
sleep ${SLEEP_TIME}
COUNT=$(($COUNT + 1))
done
if [ ! $(cat FILE_TO_CHECK | grep "${LINE_TO_CONTAIN}") ]
then
echo "Let's go, the file is containing what we want"
# Start your algorithm here
else
echo "Timed out"
exit 10
fi
$(SLEEP_TIME)
should be${SLEEP_TIME}
. There's no need to cat and pipe to grep. And uppercase variables are a bad habit.Thank you for this comment. I've already fixed the
${SLEEP_TIME}
. About the naming convention, you are right using lower case seems to be a better idea in order to not override an environment variable.Isn't the logic in the while loop reversed? This will loop as long as grep finds something, and stop when it doesn't. How about something like
until grep -q string file ; do sleep 1s ; done
?grep returns 0 when it find a match, otherwise it returns 1. unixhelp.ed.ac.uk/CGI/man-cgi?grep
Indeed, but putting it inside
[ $() ]
means the exit value of[
controlswhile
, and it will simply test whether the output of the command ($()
) is a non-empty string. You can try this withif [ $( true ) ] ; then echo true ; fi
.