13

I have an infinite while loop that I only want to break out of if the user presses Ctrl - C.

But there are 2 counters inside my while loop whose value I want printed out when I exit the while loop.

OK_COUNT=0
NOK_COUNT=0

while :
  do
    RESULT=`curl -s http://${IP}${ENDPOINT} --max-time 1`

      if [ $RESULT == '{"status":"UP"}' ]
        then
           (( OK_COUNT+=1 ))
           echo "`date` :: ${ENDPOINT} is OK ! Total count is $OK_COUNT "
        else
           (( NOK_COUNT+=1 ))
           echo "`date` :: ${ENDPOINT} is UNREACHABLE ! Total count is $NOK_COUNT"
      fi

    sleep 0.5
  done

echo $OK_COUNT
echo $NOK_COUNT

Now when I press Ctrl + C, I exit out of the while loop and out of the script too. This means the last 2 echo statements dont get to be printed.

Is there a way that if I press Ctrl + C, I only exit out of the while loop but the rest of the script still runs ?

EDIT/SOLUTION ::

After adding trap, It works !

OK_COUNT=0
NOK_COUNT=0

trap printout SIGINT
printout() {
   echo $OK_COUNT
   echo $NOK_COUNT
   exit
}

while :
  do
    RESULT=`curl -s http://${IP}${ENDPOINT} --max-time 1`

      if [ $RESULT == '{"status":"UP"}' ]
        then
           (( OK_COUNT+=1 ))
           echo "`date` :: ${ENDPOINT} is OK ! Total count is $OK_COUNT "
        else
           (( NOK_COUNT+=1 ))
           echo "`date` :: ${ENDPOINT} is UNREACHABLE ! Total count is $NOK_COUNT"
      fi

    sleep 0.5
  done

With the above code, when I exit the code with Ctrl + C, I get.

Wed Oct 18 18:59:13 GMT 2017 :: /cscl_etl/health is OK ! Total count is 471 
Wed Oct 18 18:59:13 GMT 2017 :: /cscl_etl/health is OK ! Total count is 472 
^C
5
0
# 

1 Answer 1

19

Trap Statement

Here is one method for making sure the echo statements are run after a Ctrl+C:

trap printout SIGINT
printout() {
    echo ""
    echo "Finished with count=$count"
    exit
}
while :
do
    ((count++))
    sleep 1
done

When run and Ctrl+C is pressed, the output from this script looks like:

$ bash s.sh
^C
Finished with count=2

How it works

The trap statement captures Ctrl+C and executes the function printout. That function can include any statement you like.

Subshell with trap

Alternatively, we can put the loop and the trap statement in a subshell:

$ cat t.sh
(
    trap printout SIGINT
    printout() {
        echo ""
        echo "At end of loop: count=$count"
        exit
    }
    while :
    do
        ((count++))
        sleep 1
    done
)
echo "Finishing script"

when this is run and Ctrl+C is pressed, the output looks like:

$ bash t.sh
^C
At end of loop: count=2
Finishing script

This method allows us to continue with the script after the subshell. Note, though, that any variables set or other environment changes made in the subshell are lost after the subshell exits.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for your answer. I tried your first suggestion but it does not appear to be working. I have edited my question and added my most upto date edits.
@JasonStanley I copied-and-pasted your script, added definitions for IP and ENDPOINT, and it works fine for me. So, what OS are you on? If Linux, which distribution? Also very important, how exactly are you executing your script?
Thanks for specifically mentioning "how exactly are you executing your script?". My bad. To exclude ERRORs, I was running my script with > out.log 2> /dev/null | tail -f out.log so I couldnt see the part of the script after the Ctrl + C. Now I do. Thanks again !

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.