[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: set-e and command expansion
From: |
Kerin Millar |
Subject: |
Re: set-e and command expansion |
Date: |
Sun, 4 Feb 2024 18:14:16 +0000 |
On Sun, 04 Feb 2024 20:27:56 +0300
Van de Bugger <van.de.bugger@yandex.ru> wrote:
> Hi,
>
> bash version 5.2.21(1)-release (x86_64-redhat-linux-gnu)
> Fedora Linux 38
> bash is installed from the Fedora repo, compiler I guess is gcc 13, probably
> 13.2 or 13.2.1
>
> All the test scripts follow the same scheme:
>
> #!/bin/bash
> set -e
> echo before
> COMMAND
> echo after
>
> Let's consider few COMMAND variations and script behavior.
>
> Case 1: false
>
> $ cat ./test
> #!/bin/bash
> set -e
> echo before
> false
> echo after
>
> $ ./test
> before
>
> "false" exits with status 1, so "set -e" terminates the script before "echo
> after". That's expected behavior.
>
> Case 2: var=$(false); echo $var
>
> $ cat ./test
> #!/bin/bash
> set -e
> echo before
> var=$(false); echo $var
> echo after
>
> $ ./test
> before
>
> The script is still terminated before "echo after" (actually, even before
> "echo
> $var"). I didn't find in the bash manual how bash should behave in such case,
> but it exits and I think this is ok.
This behaviour pertains to the use of Simple Commands.
Below is an excerpt from
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_01.
"If there is a command name, execution shall continue as described in Command
Search and Execution. If there is no command name, but the command contained a
command substitution, the command shall complete with the exit status of the
last command substitution performed."
Below is an excerpt from
https://www.gnu.org/software/bash/manual/html_node/Simple-Command-Expansion.html.
"If there is a command name left after expansion, execution proceeds as
described below. Otherwise, the command exits. If one of the expansions
contained a command substitution, the exit status of the command is the exit
status of the last command substitution performed."
>
> Case 3: echo $(false)
>
> $ cat ./test
> #!/bin/bash
> set -e
> echo before
> echo $(false)
> echo after
>
> $ ./test
> before
>
> after
>
> Oops, in this case the script is NOT terminated before "echo after", but
> continues to the end. I would say this is a bug, but interaction between "set
> -
It isn't a bug. In this particular case, the exit status of echo was 0, while
the exit status of the false builtin was immaterial.
The behaviour of errexit can be confusing in practice. You may find
https://mywiki.wooledge.org/BashFAQ/105 to be an interesting read.
--
Kerin Millar