[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: use of set -e inside parenthesis and conditionnal second command

From: Greg Wooledge
Subject: Re: use of set -e inside parenthesis and conditionnal second command
Date: Tue, 17 Nov 2020 09:24:48 -0500
User-agent: Mutt/1.10.1 (2018-07-13)

On Tue, Nov 17, 2020 at 09:35:35AM +0100, Pierre Colombier via Bug reports for 
the GNU Bourne Again SHell wrote:
>         I'm not sure this is actually a bug since dash act the same way but
> it's quite unexpected for the average user

Agreed!  The behavior of set -e is extremely surprising, and people should
stop expecting it to make intuitive sense.  The best way to avoid being
surprised by it is to stop using it altogether.  You will be much happier.

> and the manual suggests it should
> not act like this.

It is virtually impossible to document the behavior of set -e in a way
that a human brain can understand, because the behavior is so nonsensical.
Can you cite a specific sentence in the manual that is incorrect?

> pierre@zebulon: ~ $ (set -e ; echo A ; false ; echo B ) && echo C.$?
> A
> B
> C.0
> #Surprising

This was alerady explained a few days ago.  You've got a compound
command of the form X && Y.  The effect of set -e is suppressed in
this compound command, except if Y fails.

                      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 following the  if  or
                      elif  reserved  words, 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 value is being inverted with !.

I am guessing you are surprised that "echo B" was executed.  But the
documentation says that set -e doesn't apply to "any command executed in
a && or || list except [the last one]".

The fact that you spawned a subshell doesn't change that.  The subshell is
a fork() of the script, so it inherits all of the internal knowledge of
the parent process.  The left hand side knows it's part of a && list
and therefore doesn't honor set -e.

In the example that I snipped, you replaced the subshell with an explicit
"bash -c ...", which is NOT a subshell, and does not inherit the internal
knowledge of the parent process.  In that example, the left hand side
doesn't know that it's part of a && list in a calling scope, so it doesn't
know it should suppress set -e.  So, you get a different result.

Seriously, set -e is not a good thing.  Stop using it.

reply via email to

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