Dear maintainer,

I believe I have found a regression in bash when using subshells with
set -e. I discovered this while looking through the logs of
mirrors.mit.edu's sync jobs, and noticed that despite `set -e`, the
script did not terminate when rsync returned non-zero. In case it is
relevant, the sync scripts are available at
https://github.com/sipb/mirrors-sync; fetch-hudson is the entry point,
and ubuntu-archive is the one that I noticed triggered the behavior.

Here's the minimized test case:

```
$ cat harness.sh <(echo '---') helper
#!/bin/bash

set -e

echo "Sourcing helper"
(. helper) && :
echo "Helper exited with $?"
---
#!/bin/bash

set -e

echo "In helper"
false
echo "Should not print"
$ /bin/bash --version && /bin/bash harness.sh
GNU bash, version 3.2.57(1)-release (arm64-apple-darwin24)
Copyright (C) 2007 Free Software Foundation, Inc.
Sourcing helper
In helper
Helper exited with 1
$ bash --version && bash harness.sh
GNU bash, version 5.3.9(1)-release (aarch64-apple-darwin24.6.0)
Copyright (C) 2025 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Sourcing helper
In helper
Should not print
Helper exited with 0
```

The above output was from a macOS 15.7.3 machine, although I have
similarly verified it produces the same results on Linux (Debian
Trixie) while I was doing a bisect. Best I can tell, this behavior was
introduced in bash 4.3; 4.2 and older do not exhibit the undesired
behavior.

I also double-checked the behavior against dash (0.5.12-12 from Debian
Trixie), and dash acts like bash 4.2 and older:

```
$ dash harness.sh
Sourcing helper
In helper
Helper exited with 1
```

I believe that bash's current behavior goes against the POSIX
specification if my reading of
https://pubs.opengroup.org/onlinepubs/9799919799/utilities/V3_chap02.html
is correct.

In the meantime, I have found a workaround of disabling `set -e`
before a subshell invocation:

```
$ cat harness-workaround.sh <(echo '---') helper ; /bin/bash --version
&& /bin/bash harness-workaround.sh ; bash --version && bash
harness-workaround.sh
#!/bin/bash

set -e

set +e
echo "Sourcing helper"
(. helper)
exitstatus=$?
set -e

echo "Helper exited with $exitstatus"
---
#!/bin/bash

set -e

echo "In helper"
false
echo "Should not print"
GNU bash, version 3.2.57(1)-release (arm64-apple-darwin24)
Copyright (C) 2007 Free Software Foundation, Inc.
Sourcing helper
In helper
Helper exited with 1
GNU bash, version 5.3.9(1)-release (aarch64-apple-darwin24.6.0)
Copyright (C) 2025 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Sourcing helper
In helper
Helper exited with 1
```

Sincerely,
-Alex

Reply via email to