bug-bash
[Top][All Lists]
Advanced

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

Re: set -e in (subshells) does not work independently of outer context


From: Eric Blake
Subject: Re: set -e in (subshells) does not work independently of outer context
Date: Wed, 25 Jan 2012 09:15:29 -0700
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:9.0) Gecko/20111222 Thunderbird/9.0

[re-adding the list - also, please don't top-post on technical lists]

On 01/24/2012 06:53 PM, Jim Avera wrote:
> Thanks for the quick reply.  I read the referenced article and don't
> think it says that at all.
> (http://austingroupbugs.net/view.php?id=52).   In fact it seems to imply
> that -e *should* work inside subshell commands even if -e is otherwise
> being ignored (presumably because it is in a conditional context, etc.):
> 
> <quote>
> 3) If the exit status of a compound command **other than a subshell**
> command was the result of a failure while -e was being ignored, then -e
> shall not apply to this command. </quote> [emphasis added]
> 
> So what is the implication of this statement if the compound -is- a
> subshell command?  Why was the exception "other than a subshell command"
> specified?
> Presumably -e should apply regardless of whether it was being ignored
> outside in such cases.
> 
> I checked, and bash's current behavior matches ksh.   So it is compatible.
> 
> But as I read the specification, bash (and ksh) do something different.

Consider:

$ ksh -c 'set -e; { false && :; }; echo $?'
1
$ bash -c 'set -e; { false && :; }; echo $?'
1

This echoes 1.  Why?  Inside the compound command, we have an AND-OR
list; which means that the left half of the list is in a context where
-e is ignored (the 'false'); but based on the semantics of &&, the right
half is not executed.  That means the overall compound command (the '{
false && :; }') executed with a failure - but the _reason_ it failed was
due to a failure of the AND-OR command, which was in turn due to the
failure of the simple command 'false' in a context where -e is ignored.
 Therefore, the compound command has a non-zero status, but does not
trigger an exit for -e, even though -e is in effect for the overall
compound command.

Now, repeat the test with a subshell:

$ ksh -c 'set -e; ( false && : ); echo $?'
$ bash -c 'set -e; ( false && : ); echo $?'

Notice - no exit status.  Why?  Because sub-shells are the only compound
command where a non-zero status, caused for any reason (including
reasons where set -e was ignored), is fatal to the parent script.

That's what point 3 is trying to tell you.

Point 3 is _not_ requiring subshells to override the contexts where set
-e is ignored.  That is, once you are in a context where -e is ignored,
there is NOTHING you can do to get -e obeyed again, not even a subshell.

$ bash -c 'set -e; if (set -e; false; echo hi); then :; fi; echo $?'
hi
0

Even though we called set -e twice (both in the parent and in the
subshell), the fact that the subshell exists in a context where -e is
ignored (the condition of an if statement), there is nothing we can do
in the subshell to re-enable -e.

-- 
Eric Blake   eblake@redhat.com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

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