2

I am trying to get a shell script to recognize when an app instance has come up. That way it can continue issuing commands.

I've been thinking it would be something like this:

#/bin/bash

startApp.sh

while [ `tail -f server.log` -ne 'regex line indicating success' ]
do

sleep 5

done

echo "App up"

But, even if this worked, it wouldn't address some concerns:

  • What if the app doesn't come up, how long will it wait
  • What if there is an error when bringing the app up
  • How can I capture the log line and echo it

Am I close, or is there a better way? I imagine this is something that other admins have had to overcome.

EDIT:

I found this on super user

https://superuser.com/questions/270529/monitoring-a-file-until-a-string-is-found

tail -f logfile.log | while read LOGLINE
do
   [[ "${LOGLINE}" == *"Server Started"* ]] && pkill -P $$ tail
done

My only problem with this is that it might never exit. Is there a way to add in a maximum time?

Community
  • 1
  • 1
tpederson
  • 516
  • 1
  • 5
  • 12

2 Answers2

4

Ok the first answer was close, but didn't account for everything I thought could happen.

I adapted the code from this link:

Ending tail -f started in a shell script

Here's what I came up with:

#!/bin/bash

instanceDir="/usr/username/server.name"
serverLogFile="$instanceDir/server/app/log/server.log"

function stopServer() {

    touch ${serverLogFile}

    # 3 minute timeout.
    sleep 180 &
    local timerPid=$!

    tail -n0 -F --pid=${timerPid} ${serverLogFile} | while read line 
    do
        if echo ${line} | grep -q  "Shutdown complete"; then
          echo 'Server Stopped'
          # stop the timer..
          kill ${timerPid} > /dev/null 2>&1
        fi
    done &

    echo "Stoping Server."
    $instanceDir/bin/stopserver.sh > /dev/null 2>&1

    # wait for the timer to expire (or be killed)
    wait %sleep


}

function startServer() {

    touch ${serverLogFile}

    # 3 minute timeout.
    sleep 180 &
    local timerPid=$!

    tail -n0 -F --pid=${timerPid} ${serverLogFile} | while read line 
    do
        if echo ${line} | grep -q  "server start complete"; then
          echo 'Server Started'
          # stop the timer..
          kill ${timerPid} > /dev/null 2>&1
        fi
    done &

    echo "Starting Server."
    $instanceDir/bin/startserver.sh > /dev/null 2>&1 &

    # wait for the timer to expire (or be killed)
    wait %sleep

}

stopServer
startServer
Community
  • 1
  • 1
tpederson
  • 516
  • 1
  • 5
  • 12
  • What happens if the statup fails ? – Mehdi Jun 19 '17 at 14:35
  • Well, this is kind of old, but if the startup fails, you should see that on the console and hit ctrl-c to exit. Ultimately the --pid flag would see that the sleep proc exited in 180 seconds, and terminate the tail, which would eventually cause the entire script to exit. – tpederson Jun 19 '17 at 20:23
2

Well, tail -f won't ever exit, so that's not what you want.

numLines=10
timeToSleep=5
until tail -n $numLines server.log | grep -q "$serverStartedPattern"; do 
  sleep $timeToSleep
done

Be sure that $numLines is greater than the number of lines that might show up during $timeToSleep when the server has come up.

This will continue forever; if you want to only allow so much time, you could put a cap on the number of loop iterations with something like this:

let maxLoops=60 numLines=10 timeToSleep=5 success=0
for (( try=0; try < maxLoops; ++try )); do 
  if tail -n $numLines server.log | grep -q "$serverStartedPattern"; then
    echo "Server started!"
    success=1
    break
  fi
  sleep $timeToSleep
done

if (( success )); then
  echo "Server started!"
else 
  echo "Server never started!"
fi

exit $(( 1-success ))
Mark Reed
  • 91,912
  • 16
  • 138
  • 175
  • I thought about that, my only concern is that when loading the java process it can output hundreds of lines every second. So if I set it high enough to compensate for that, it might catch a previous restart and give a false positive. – tpederson Sep 13 '12 at 20:15