[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: errexit is not respected on nested functions when parent function pr
From: |
Lawrence Velázquez |
Subject: |
Re: errexit is not respected on nested functions when parent function preceeds || |
Date: |
Tue, 08 Aug 2023 17:29:56 -0400 |
User-agent: |
Cyrus-JMAP/3.9.0-alpha0-624-g7714e4406d-fm-20230801.001-g7714e440 |
On Tue, Aug 8, 2023, at 12:04 PM, cirrus.mazurka-0t--- via Bug reports for the
GNU Bourne Again SHell wrote:
> The following code:
>
> ``` bash
> #!/usr/bin/env bash
>
> set -Eeuo pipefail
> shopt -s huponexit
> shopt -s inherit_errexit
>
> function child_function {
> return 1
> }
> function parent_function {
> child_function
> echo "parent noticed child exit code as $?"
> }
> function grandparent_function {
> local ec
> ec=0 && parent_function || ec="$?"
Commands in AND-OR lists are not subject to set -e, with the exception
of the final command. So within this particular parent_function
call the failing child_function command does not cause an early
exit. Instead, echo is run, and its exit status (0) becomes that
of parent_function.
> echo "grandparent noticed parent exit code as $ec"
> }
>
> grandparent_function
> ```
>
> Will surprisingly output:
>
> ```
> parent noticed child exit code as 1
> grandparent noticed parent exit code as 0
This behavior may surprise you, but it is documented [1]. It also
conforms to POSIX [2] and is quite common:
[1]: https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html
[2]:
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#set
% cat foo.sh
set -e
child_function() {
return 1
}
parent_function() {
child_function
echo "parent noticed child exit code as $?"
}
grandparent_function() {
ec=0 && parent_function || ec="$?"
echo "grandparent noticed parent exit code as $ec"
}
grandparent_function
% bash foo.sh
parent noticed child exit code as 1
grandparent noticed parent exit code as 0
% ksh foo.sh
parent noticed child exit code as 1
grandparent noticed parent exit code as 0
% mksh foo.sh
parent noticed child exit code as 1
grandparent noticed parent exit code as 0
% zsh foo.sh
parent noticed child exit code as 1
grandparent noticed parent exit code as 0
% dash foo.sh
parent noticed child exit code as 1
grandparent noticed parent exit code as 0
% yash foo.sh
parent noticed child exit code as 1
grandparent noticed parent exit code as 0
(These are bash 5.2.15, ksh93u+ 2012-08-01, mksh R59 2020/10/31,
zsh 5.9, dash 0.5.11.5, and yash 2.54.)
> Changing the code to:
>
> ``` bash
> #!/usr/bin/env bash
>
> set -Eeuo pipefail
> shopt -s huponexit
> shopt -s inherit_errexit
>
> function child_function {
> return 1
> }
> function parent_function {
> child_function || return "$?"
> echo "parent noticed child exit code as $?"
> }
> function grandparent_function {
> local ec
> ec=0 && parent_function || ec="$?"
> echo "grandparent noticed parent exit code as $ec"
> }
>
> grandparent_function
> ```
>
> Returns the expected result of:
>
> ```
> grandparent noticed parent exit code as 1
This version of parent_function returns early, but not because of
set -e. In fact, now *every* parent_function invocation exempts
child_function from set -e.
What exactly is the behavior you expect?
> Is there an additional setting that I need to set to fix this? Or is
> this a bug in bash?
It is not a bug, and as far as I know there is no setting.
Here is some additional reading on set -e wrinkles:
https://mywiki.wooledge.org/BashFAQ/105
https://mywiki.wooledge.org/BashPitfalls#errexit
--
vq