bug-bash
[Top][All Lists]
Advanced

[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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]