Invocation in for loop function does not fail even with "set -e"
Consider the following simple bash script:
#!/bin/bash
set -eou pipefail
IFS=$'\n\t'
gen() {
seq 0 3
}
for c in $(gen); do
echo c
done
echo "finish"
It has set -e
, so when something fails, it should just exit with a non-zero exit code.
It will call the function gen
and print the output seq 0 3
, print finish
and exit with code = 0.
If I change gen
to fail, say by calling a command seqqq
(which doesn't exist):
$ ./script.sh; echo $?
./script.sh: line 6: seqqq: command not found
finish
0
It prints the error message from the sub-shell, it doesn't terminate immediately and exits (with a non-zero code) immediately, as expected set -e
; it continues to execute and exits with code = 0.
What is the explanation for this? Note that if I just replace the for loop like this, it doesn't work as expected:
#!/bin/bash
set -eou pipefail
IFS=$'\n\t'
gen() {
seqqq 0 3
}
gen # <-- fails and exits here with code=127
echo "finish"
source to share
Seems to be set -e
ineffective in the context of command substitution, as in:
for c in $(gen); do
echo c
done
However, it set -e
works in the context of a direct function call, as in:
gen
It is difficult or nearly impossible to write robust shell scripts with set -e
. Use explicit error handling instead. You can read more about this here: BashFAQ / 105
source to share