[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 ebl...@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
signature.asc
Description: OpenPGP digital signature