Reputation: 49
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?
Upvotes: 0
Views: 6500
Reputation: 3615
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 ))
Upvotes: 1
Reputation: 7317
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.
Upvotes: 1