0

I want to check if an application up and running by accessing the "health check" link, so I want to implement the following logic: if it returns 200 the script stops working with exit code 0, but if it returns something else the script stops working with exit code 1, but I want to test the "health check" link 3 times in a row. So I did this

#!/bin/bash

n=0

until [ "$n" -ge 3 ]
do
    i=`curl -o /dev/null -Isw '%{http_code}\n' localhost:8080`
    if [ "$i" == "200" ]
    then
        echo "Health check is OK"
        break
    else
        echo "Health check failed"
    fi

    n=$((n+1))
    sleep 5
done

When it's 200 and break is triggered, it exits with exit code 0, which is fine, but I also want it to exit with exit code 1 if it's not 200 but after the third iteration of the until loop. If I add exit 1 inside or below the "if statement" the script exits with exit code 1 but after the first iteration.

Is there any way to make it exit with exit code 1 after the third iteration of the loop?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Oleg
  • 43
  • 1
  • 6

5 Answers5

4

You could immediately exit 0 inside the loop when the health check passes, and exit 1 after the loop.

n=0

until [ "$n" -ge 3 ]
do
    i=`curl -o /dev/null -Isw '%{http_code}\n' localhost:8080`
    if [ "$i" == "200" ]
    then
        echo "Health check is OK"
        exit 0
    else
        echo "Health check failed"
    fi

    n=$((n+1))
    sleep 5
done

exit 1
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
2

Is there any way to make it exit with exit code 1 after the third iteration of the loop?

If we always want to exit 1 if any of the requests resulted in != 200, we can use a simple flag:

#!/bin/bash

n=0
failed=false

until [ "$n" -ge 3 ]
do
    i=`curl -o /dev/null -Isw '%{http_code}\n' localhost:8080`
    if [ "$i" == "200" ]
    then
        echo "Health check is OK"
    else
        echo "Health check failed"
        failed=true
    fi

    n=$((n+1))
    sleep 5
done

if [ "$failed" = true ] ; then
    exit 1
else
    exit 0
fi

Some additional tips to shorten the code:

  • We can remove the n variable by using a for loop
  • An short-if to exit
#!/bin/bash

failed=false

for (( i = 0; i < 3; i++ )); do

    r=`curl -o /dev/null -Isw '%{http_code}\n' localhost:8080`

    if [ "$r" == "200" ]; then
        echo "Health check is OK"
    else
        echo "Health check failed"
        failed=true
    fi

    sleep 5
done

[[ "$failed" = true ]] && exit 1 || exit 0
0stone0
  • 34,288
  • 4
  • 39
  • 64
2

See #>>> notes:

#!/bin/bash

n=0
#>>> default status if never successful
status=1

until [ "$n" -ge 3 ]
do
    i=`curl -o /dev/null -Isw '%{http_code}\n' localhost:8080`
    if [ "$i" == "200" ]
    then
        echo "Health check is OK"
        #>>> successful: set status to 0
        status=0
        break
    else
        echo "Health check failed"
    fi

    n=$((n+1))
    sleep 5
done

#>>> exit with $status
exit $status
Wiimm
  • 2,971
  • 1
  • 15
  • 25
2

You don't need an extra boolean variable, if you set the status before the end of the loop. So move your counter update and sleep timer into the failed check branch:

#!/usr/bin/env sh

n=0
until [ "$n" -ge 3 ]; do
  i=$(curl -o /dev/null -Isw '%{http_code}\n' localhost:8080)
  if [ "$i" -eq 200 ]; then
    echo "Health check is OK"
    break
  else
    echo "Health check failed"
    n=$((n + 1))
    sleep 1
    false # Set status to false
  fi
done
Léa Gris
  • 17,497
  • 4
  • 32
  • 41
2
#!/bin/sh

c=3
until
  i=$(curl -Isw '%{http_code}' -o /dev/null localhost:8080)
  [ "$i" = 200 ]
do
  echo 'Health check failed' >&2
  [ "$c" -gt 1 ] || exit
  c=$((c-1))
  sleep 5
done

echo 'Health check is OK' >&2

With the loop restructured this way (i.e. until <success> ...), the state of the counter variable can be used to exit after the last try. Having the counter start at n and decrease towards zero simplifies using and testing the variable. Also, sleep 5 after the nth failure is avoided.