0

I am trying to do a for loop in Bash and exit on an if statement but I realised it will break the code before finishing the loop.

#!/bin/bash

for node in $(ps -ef | awk <something>);
do

  var=<command>
  echo "node ${node}"

  if [[ ${var} -gt 300000 ]]; then
    echo "WARNING!";
    exit 1;

  elif [[ ${var} -gt 1000000 ]]; then
    echo "CRITICAL!";
    exit 2;

  else
    echo "OK!";
    exit 0;
  fi
done

My second option is to set a variable instead of the exit outside the loop but then I realised it will override each node status:

#!/bin/bash

for node in $(ps -ef | awk <command>);
do

  var=<command>
  echo "node ${node}"

  if [[ ${var} -gt 300000 ]]; then
    echo "WARNING!";
    status="warning"

  elif [[ ${var} -gt 1000000 ]]; then
    echo "CRITICAL!";
    status="critical"

  else
    echo "OK!";
    status="ok"
  fi
done

if [[ status == "warning" ]]; then 
  exit 1;
elif [[ status == "critical" ]]; then 
  exit 2;
elif [[ status == "ok" ]]; then 
  exit 0;
fi 

How do I exit properly on each node?

3
  • If you get a mix of statuses (like some oks, some warnings, maybe a critical or two), what do you want it to do? Should it only report the most severe status, or print all errors and exit with the most severe status, or... Commented Feb 20, 2020 at 8:41
  • I want it to send an exit code for different node Commented Feb 20, 2020 at 8:58
  • Maybe use an array to store the data and once the loop has finished , use the array to revisit the statuses and do the necessary computation. Also , when you say send an exit code , in your above script I don’t think you are sending any exit code. A shell script can exit just once Commented Feb 20, 2020 at 9:26

2 Answers 2

2

Use continue operator, from man bash

...
       continue [n]
              Resume the next iteration of the enclosing for, while, until, or select loop.  If n is specified, resume at the nth enclosing loop.  n must be
              ≥ 1.  If n is greater than the number of enclosing loops, the last enclosing loop (the ``top-level'' loop) is resumed.  The return value is  0
              unless n is not greater than or equal to 1.

Or break if you need to exit from loop

...
       break [n]
              Exit  from within a for, while, until, or select loop.  If n is specified, break n levels.  n must be ≥ 1.  If n is greater than the number of
              enclosing loops, all enclosing loops are exited.  The return value is 0 unless n is not greater than or equal to 1.
Sign up to request clarification or add additional context in comments.

1 Comment

This won't work. The break will break the loop which is not what I am intending to do. The continue won't make it either as it is not taking in consideration the exit code.
1

Here is an alternative. It counts the results and and creates an exit status depending on the counters. I changed the semantic, because your script never reaches the CRITICAL path. Instead the WARNING path was entered for values >1000000:

#!/bin/bash

let ok_count=0 warn_count=0 critical_count=0

for node in $(ps -ef | awk <command>);
do

  var=<command>
  echo "node ${node}"

  # >1000000 must be checked before >300000
  if [[ ${var} -gt 1000000 ]]; then
    echo "CRITICAL!";
    let critical_count++

  elif [[ ${var} -gt 300000 ]]; then
    echo "WARNING!";
    let warn_count++

  else
    echo "OK!";
    let ok_count++
  fi
done

if ((critical_count)); then 
  exit 2
elif ((warn_count)); then 
  exit 1
else
  exit 0
fi

This script can be optimized, if only the exit status is needed: CRITICAL is the highest warn level. So counting is not necessary. OK is the fallback. So counting is not necessary.

#!/bin/bash

let warn_count=0

for node in $(ps -ef | awk <command>);
do

  var=<command>
  echo "node ${node}"

  if [[ ${var} -gt 1000000 ]]; then
    echo "CRITICAL! -> abort";
    exit 2 # no more analysis needed!

  elif [[ ${var} -gt 300000 ]]; then
    echo "WARNING!";
    let warn_count++
  fi
done

exit $(( warn_count > 0 ))

1 Comment

You are right @Wimm, in the end, if one of the node has a critical status it is enough to exit.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.