mainThe GNU Bourne-Again SHell - Support: sr #109540, shopt -s inherit_errexit does not...


sr #109540: shopt -s inherit_errexit does not work on all command substitutions

Submitter:  Björn Kautler <vampire0>
Submitted:  Thu 09 Aug 2018 02:31:52 PM UTC
Category:  None Priority:  5 - Normal
Severity:  3 - Normal Status:  Invalid
Privacy:  Public Assigned to:  None
Open/Closed:  Open Operating System:  None
* Mandatory Fields

Add a New Comment Rich Markup

Jump to the original submission

Fri 24 Aug 2018 08:02:41 PM UTC, comment #9: 

No, a variable assignment, or, more precisely a command that does not result in any words after word expansion, is the only place where the exit status of a command substitution matters.

Chet Ramey <chet>
Group administrator
Fri 24 Aug 2018 01:12:18 PM UTC, comment #8: 

Ah, I see, so i just misinterpreted the text and the `-e` is not as helpful as I hoped for finding failures.

There is no setting or shopt that would make the script fail in this case and the one in the other ticket, is there?

Besides of course doing the command substitution in a variable assignment and using the variable assignment in the arguments or here-docs, so that the variable assignment is the one that fails.

Thanks for your patience btw. :-)

Björn Kautler <vampire0>
Thu 23 Aug 2018 02:57:12 PM UTC, comment #7: 

It says exactly the opposite.

"If there is a command name left after expansion, execution proceeds as described below."

"Described below" means the COMMAND EXECUTION section. The remainder of that paragraph describes what happens if there is not a command name left after word expansion.

The subsequent text describes how the command (`echo') is invoked and how the shell collects its exit status.

Chet Ramey <chet>
Group administrator
Thu 23 Aug 2018 02:33:51 PM UTC, comment #6: 

But if it applies, shouldn't it fail then? confused

Björn Kautler <vampire0>
Mon 20 Aug 2018 03:49:48 PM UTC, comment #5: 

No. The first sentence in the section you quoted applies, since there is a command name (`echo') remaining after all the words are expanded.

Chet Ramey <chet>
Group administrator
Mon 20 Aug 2018 02:18:04 PM UTC, comment #4: 

Please excuse if I ask again, now with another piece of documentation you pointed me at in the other issue. says:

> 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. If there were no command substitutions, the command exits with a status of zero.

Doesn't that mean that the `echo` should exit with the exit status of the last command substitution which is the `$(echo inside; false; true)'?

Or to which case does that sentence refer to?

Maybe the docs would benefit from some examples.

Björn Kautler <vampire0>
Mon 20 Aug 2018 02:06:07 PM UTC, comment #3: 

The `$(echo inside; false; true)' is not a command, so it is not subject to any of the conditions under which the shell will exit. It is a word expansion.

That word expansion does not affect the exit status of the `echo', which exits successfully if it writes its arguments to the standard output.

Chet Ramey <chet>
Group administrator
Mon 20 Aug 2018 12:37:06 PM UTC, comment #2: 

Well, I read the documentation of `-e` on the page

There it says:

> Exit immediately if a pipeline (see Pipelines), which may consist of a single simple command (see Simple Commands), a list (see Lists), or a compound command (see Compound Commands) returns a non-zero status.
> The shell does not exit if the command that fails is part of the command list immediately following a while or until keyword, part of the test in an if statement, part of any command executed in a && or || list except the command following the final && or ||, any command in a pipeline but the last, or if the command’s return status is being inverted with !.

As far as I can tell the `echo $(echo inside; false; true)` does not qualify for the second quoted line. The failing command is not following `while` or `until`, it is not part of the test in an `if`, it is not part of a `&&` or `||` list, it is not part of  a pipeline and its status is not inverted with `!`. So from the documentation I would have expected the second script to fail the same way as the first one does.

Can you explain to me why this is not the case?

Björn Kautler <vampire0>
Fri 17 Aug 2018 01:50:15 PM UTC, comment #1: 

I'm not sure where the supposed problem is. In the second example, the exit status of the command substitution does not affect the return status of the `echo', so the script does not exit.

In the first example, on the other hand, the return status of the variable assignment is defined to be the exit status of the command substitution, which is 1, so the script honors -e and exits.

Chet Ramey <chet>
Group administrator
Thu 09 Aug 2018 02:31:52 PM UTC, original submission:  

This script will properly not continue after the command substitution and not print anything:

#!/usr/bin/env bash

set -e
shopt -s inherit_errexit
output=$(echo inside; false; true)
echo $output
echo after

But this script will incorrectly(?) print "inside" and "after":

#!/usr/bin/env bash

set -e
shopt -s inherit_errexit
echo $(echo inside; false; true)
echo after

Björn Kautler <vampire0>


(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:

No files currently attached


Depends on the following items: None found

Items that depend on this one: None found


Carbon-Copy List
  • -email is unavailable- added by chet (Posted a comment)
  • -email is unavailable- added by vampire0 (Submitted the item)

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only logged-in users can vote.


    Follows 1 latest change.

    Date Changed by Updated Field Previous Value => Replaced by
    2018-08-17 chet StatusNone Invalid

    Back to the top

    Powered by Savane 3.12.
    Corresponding source code