Subject: Re: make -j and failure modes
To: Robert Elz <kre@munnari.OZ.AU>
From: James Chacon <jmc@NetBSD.org>
Date: 12/10/2003 10:45:04
On Wed, Dec 10, 2003 at 10:22:09PM +0700, Robert Elz wrote:
> Date: Wed, 10 Dec 2003 14:48:28 +0000 (GMT)
> From: Ben Harris <bjh21@NetBSD.org>
> Message-ID: <Pine.SOL.firstname.lastname@example.org>
> | On Wed, 10 Dec 2003, James Chacon wrote:
> | > The subshell should exit by normal rules and based on the fact that -e
> | > transfers to it. (and return according to the rules for subshells
> | > which is the exit code from the last command).
> | >
> | > Past that I think it's obvious then that the parent would exit as it's got
> | > the e flag set and it just had a command exit non-zero and it's not part
> | > of the exclusion list of ones to ignore for checking on error.
> | So you think that that the parent should treat the entire group of
> | commands in the subshell as a single command, and exit if it fails, yes?
> I think that's what he is saying, but I believe it is clearly wrong.
> It is absurd to require the shell to look inside the commands run by the
> sub-shell and see if they're the kind that should cause "set -e" mode to
> cause the shell to exit - but not doing so would mean the parent shell exiting
> if the sub-shell exits with an error code, even though that error code didn't
> actually cause the sub-shell to exit 1 because of the -e.
Actually I was saying the parent shell would exit because the sub-shell
returned non-zero for *any* reason. At that point the sub shell is just
a process returning an exit code.
> That is, a couple of examples...
> delta$ sh -ec 'false && echo foo'
> no output, of course, false is false...
> delta$ sh -ec 'false || echo foo'
> the "false" does not cause the shell to exit, because it is in a ||
Both of these are excluded from -e tests anyways. It lists exceptions for
AND and OR.
> sh -ec 'false && echo foo
> echo ok'
> Same here, no "foo", no exit from the shell either.
As it shouldn't (due to the && exception)
> delta$ sh -ec 'false || false'
> delta$ echo $?
> Shell exit's 1 from this, but that's because false does exit 1, not
> because of -e
Again, not valid for -e as || is excepted.
> delta$ sh -ec '(false && echo bad) ; echo ok'
> what was being requested was that this one should not do the echo ("ok")
> because of the sub-shell doing the exit 1 (because of executing the
> false command, not because of set -e).
Why the subshell returned 1 is up to the subshell (it could very well have
turned off -e, that's it's business). The fact it returned a non-zero exit
code is what's important to the parent shell.
> That's too dumb to contemplate, and attempting to write either the code,
> or the specification, to make anything different happen is way too complex
> to even consider.
For what reason? The command in question exited non-zero for some reason.
Whatever the reason was it's concern. The parent process though is set to
exit (via -e) for anything that returns non-zero and this would meet that
criteria since it isn't in the exception list for -e.
> The underlying problem here, in the original example, wasn't the sub-shell
> in any case, it was the "&&" - which clearly causes the -e to be ignored
> (whether the command that fails is the first, or second, in the && sequence).
> That much is beyond doubt.
No. It was the subshell exiting non-zero that's being ignored. Run a make rule
via make -j (which feeds that into sh -ev) and echo foo will be printed.
Not exactly expected behavior from make at all.
--- all ---