The significant change isn't any combination of «set -e», «set -o errexit» and/or «shopt -s execfail», but rather the insertion of «exec».
The "exit on failure" is one of the minor differences between an interactive shell and a non-interactive one, including a subshell of an interactive shell It is sufficiently demonstrated by: ( exec /no/such/path || echo In Subshell ) exec /no/such/path || In Interactive Shell without any use of set-e, errexit, or execfail. -Martin On Thu, 24 Sept 2026, 10:29 Zev Weiss, <[email protected]> wrote: > Hello, > > I've just noticed that the combination of 'set -e' and 'shopt -s > execfail' produces (to me) surprising behavior. > > Each on its own works as expected: > > $ bash -c 'set -e; /bin/enoent; echo foo' > bash: line 1: /bin/enoent: No such file or directory > $ bash -c 'set -e; /bin/enoent || echo foo' > bash: line 1: /bin/enoent: No such file or directory > foo > $ bash -c 'shopt -s execfail; exec /bin/enoent || echo foo' > bash: line 1: /bin/enoent: No such file or directory > foo > > But when combined, an exec failure exits immediately even when it's the > left operand of '||' (or an 'if' condition): > > $ bash -c 'set -e; shopt -s execfail; exec /bin/enoent || echo foo' > bash: line 1: /bin/enoent: No such file or directory > > (Note the lack of output from the 'echo' command.) > > $ echo $BASH_VERSION > 5.3.0(1)-release > > Is this a bug, or expected behavior for some subtle reason? (If the > latter I think it might be helpful to clarify somewhere in the bash man > page.) > > > Thanks, > Zev Weiss > > >
