Repeatedly fetching a URL until the response contains "state: INIT" I am working on a project in which I need to make a URL call to one of my servers from a bash shell script.

 http://hostname.domain.com:8080/beat


After hitting the above URL, I will be getting the below response, from which I need to parse and extract the value of state:

num_retries_allowed: 3 count: 30 count_behind: 100 state: INIT num_rounds: 60 hour_col: 2 day_col: 0


Now I will keep on hitting the above URL every 10 seconds until the value of the state variable is equal to INIT:

state = INIT


If the state is equal to INIT then I will exit successfully out of the shell script, otherwise I will keep on trying until the state becomes INIT. 

Also, if the state: string is missing in the $DATA variable by any chance, then I want to assign 0 to the state variable. So if state is equal to 0, then I will also exit out of the shell script successfully.

I am hitting the above URL and checking whether I got a successful response or not. If I got a successful response, then I am breaking out (which means server is running fine), but if I didn't got successful response, then I am checking whether my server is running or not on port 8080. If it is not running, then I will start the server. And I am retrying this for a period of 15 times, and after 15 tries if the server hasn't come back up, then exit out of the shell script with a non-zero status code.

Is the below shell script correct?

#!/bin/bash

HOSTNAME=$hostname
DATA=""
RETRY=15

echo $HOSTNAME

sleep 1m

while true; do

    while [ $RETRY -gt 0 ]
    do
        DATA=$(wget -O - -q -t 1 http://$HOSTNAME:8080/beat)
        if [ $? -eq 0 ]
        then
            break
        else
            if lsof -Pi :8080 -sTCP:LISTEN -t &gt;/dev/null ;
            then
                echo "Server is running"
            else
                echo "Server is not running so re-starting the server here"
                # starting server here
            fi
            let RETRY-=1
            sleep 30
        fi
    done

    if [ $RETRY -eq 0 ]
    then
        echo "Server is still down. Exiting out now." &gt;&amp;2
        exit 2
    fi

    echo "Server is up. Now parsing the data out of the beat."

    #grep $DATA for state
    state=$(grep -oP 'state: \K\S+' &lt;&lt;&lt; "$DATA")
    [[ -z "$state" ]] &amp;&amp; state=0

    echo $state

    #verify the condiitons
    if [[ $state -eq "INIT" || $state -eq "0" ]]; then exit 0; fi

    #wait another 10 seconds
    sleep 10

done


Is there any better way of doing this if I am doing anything wrong?
Inconsistent logic

In one place the script checks http://$HOSTNAME:8080/beat,
in another, it checks for a local process listening on port 8080.
This only makes sense if $HOSTNAME the name of the local machine.
It will make more sense to replace $HOSTNAME with hard-coded localhost.

Use exit code directly

Instead of this:


DATA=$(wget -O - -q -t 1 http://$HOSTNAME:8080/beat)
if [ $? -eq 0 ]
then
    break



You could use the exit code directly like this:

if DATA=$(wget -O - -q -t 1 http://$HOSTNAME:8080/beat)
then
    break


Another way:

DATA=$(wget -O - -q -t 1 http://$HOSTNAME:8080/beat) &amp;&amp; break


Math in Bash

Instead of this:


let RETRY-=1



There are slightly simpler alternatives:

((RETRY -= 1))
((RETRY--))