I ran into a sneaky bash issue today that left me scratching my head. A script with set -e
was continuing to run even after a command in the script failed.
Turns out this is documented behavior in bash, not a bug. For loops are compound commands and according to the Bash manual:
The shell does not exit if the command that fails is ... part of any command executed in a && or || list except the command following the final && ... If a compound command other than a subshell returns a non-zero status because a command failed while -e was being ignored, the shell does not exit.
For a for loop,
The return status is the exit status of the last command that executes.
Let's put this to the test with a simple script:
#!/bin/bash
set -e
for x in {1..3}; do
if [ "$x" = 2 ]; then
echo "fail"
false # the script does not exit here
fi
echo "$x"
done && \
echo "done" # this runs!
Output:
1
fail
2
3
done
One of the many idiosyncracies of our old friend bash.