How to get the exit status a loop in bash

Something like this?

while true; do
    case $RANDOM in *0) exit 27 ;; esac
done

Or like this?

rc=0
for file in *; do
    grep fnord "$file" || rc=$?
done
exit $rc

The real question is to decide whether the exit code of the loop should be success or failure if one iteration fails. There are scenarios where one make more sense than the other, and other where it's not at all clear cut.


The status of the loop is the status of the last command that executes. You can use break to break out of the loop, but if the break is successful, then the status of the loop will be 0. However, you can use a subshell and exit instead of breaking. In other words:

for i in foo bar; do echo $i; false; break; done; echo $?  # The loop succeeds
( for i in foo bar; do echo $i; false; exit; done ); echo $? # The loop fails

You could also put the loop in a function and return a value from it. eg:

in() { local c="$1"; shift; for i; do test "$i" = "$c" && return 0; done; return 1; }

The bash manual says:

while list-1; do list-2; done
until list-1; do list-2; done
  [..]The exit status of the while and until commands is the exit status
  of the last command executed in list-2, or zero if none was executed.[..]

The last command that is executed inside the loop is break. And the exit value of break is 0 (see: help break).

This is why your program keeps exiting with 0.

Tags:

Linux

Shell

Bash