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"

      

+3


source to share


1 answer


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

+4


source







All Articles