I know this question has been asked a lot of time, but trust me i have tried many suggestions. What i am trying to do is continiously monitor the logfile of a tomcat server to detect its startup. Its based on this stack post
I have modified it a little bit to add a timeout so that it won't wait for ever if the string is not present at all in the file. The code looks like below.
echo 0 > flag
timeout $DEPLOY_WAIT tail -n0 -F $TOMCAT_LOG | while read LOGLINE
do
[[ "${LOGLINE}" == *"INFO: Server startup in"* ]] && echo 1 > flag && pkill -P $$ timeout
done
x=$(cat flag)
if [ $x -ne 0 ];then
Here you can see i am writing to a flag file to detect whether the tail timed out out or if it found a matching string in the file. If i change it to a variable like
flag=0
timeout $DEPLOY_WAIT tail -n0 -F $TOMCAT_LOG | while read LOGLINE
do
[[ "${LOGLINE}" == *"INFO: Server startup in"* ]] && flag=1 && pkill -P $$ timeout
done
if [ $flag -ne 0];then
then the variable flag always have the value 0. The update done in the while loop is lost. I did some research and found out that this is because the pipe is causing bash to spawn a new sub shell and parameter are passed from parent to child and not vice versa. A solution suggested by this post was to rewrite the thing without using pipes like
flag=0
while read LOGLINE;
do
[[ "${LOGLINE}" == *"INFO: Server startup in"* ]] && flag=1 && pkill -P $$ timeout
done <<< $(timeout $DEPLOY_WAIT tail -n0 -F $TOMCAT_LOG)
if [ $flag -ne 0];then
The problem with this solution is that the data is give to the while loop only after the command timeout completes[and the code to detect the timeout process and kill it also changes. But doesn't matter, so not included] and i am not able to detect the string as soon as it arrives in the file. The script waits for the period of the timeout, no matter what. I am looking for way to combine the two into a single elegant solution not using files as flag.