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
>
>
>

Reply via email to