Pergunta

If i use -e option in bash script and code fail - i can catch it:

$ set -e; ( false; echo qwe; ) || echo qwe
qwe

But, when i try get return code i get:

$ (set -e; ( false; echo qwe; ) || ret=$?; echo asd  )
qwe
asd

Why it happens and how i can get return code?

Vesion:

$ bash --version
GNU bash, версия 4.2.37(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
Foi útil?

Solução

 set -e; ( false; echo qwe; ) || echo qwe

doesn't do what you think it does:

  • any subshell (( ... )) containing a list of commands (false; echo qwe) will execute all commands in that list and decide based on the last command's exit code whether to abort the subshell (due to -e); since echo qwe, as the subshell's last command returns 0 as its exit code (signaling succcess), the subshell returns 0 overall, and so the right side of || never kicks in; try with distinct strings to echo: set -e; ( false; echo qwe1; ) || echo qwe2

  • Trying to set a variable (ret, in this case) in a subshell for access in the originating shell is always pointless, because its scope will be confined to that subshell; to pass a value out from a subshell, use stdout output.

To achieve your goal, forget about set -e and instead suffix each command in the subshell with || exit in order to abort right away in case of failure; the exit code on leaving the subshell will then correctly reflect the exit code of the first failed command, or 0, if all commands succeeded:

output=$( false || exit; echo qwe || exit )  # capture output from subshell
ret=$?  # $? reflects overall success of subshell
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top