Subject: Re: make -j and failure modes
To: Robert Elz <kre@munnari.OZ.AU>
From: Greywolf <greywolf@starwolf.com>
List: tech-userlevel
Date: 12/11/2003 13:53:32
Thus spake Robert Elz ("RE> ") sometime Tomorrow...

RE>
RE>   | I think it is.  To have () behave differently than a raw command
RE>   | just because it's ()d makes zero sense.

RE>
RE> Hmm ...
RE>
RE> 	cd /tmp
RE> 	(cd /tmp)
RE>
RE> "To have () behave differently than a raw command just because it's ()d
RE> makes zero sense."
RE>
RE> Really?

Oh, pfaugh, you *know* what I meant!  In the context of sh -e!  *L*

OBVIOUSLY, because () is a subshell, nothing which happens in the subshell
will affect the rest of the shell.  I meant that (cmd) and cmd have the
same effect on the exit status so the shell ought to exit if -e is set.
NOTE:  This applies to the above -- I've since given some thought.
I still disagree, but disagreeing doesn't help, especially in the face
of POSIX compliance.

RE> Consider the two cases carefully, and I think you'll see that the two
RE> cases are remarkably similar.  In both the internal sub-shell is
RE> affected (in the "false" case, that shell exits, as set -e requests,
RE> in the cd case, its $PWD is altered).  In neither case is the other
RE> shell affected in the same way.

Well, that's a stretch, I think, but that's just me.

But my point was that since '(cmd); cmd' is really two separate commands,
since the () exited with 1, the second unprotected cmd should never run.
Obviously, as I note, I have relied on old behaviour, and yes, I see
what POSIX specified...

RE> The "it turns out" is no surprise, all sh grouped commands return the exit
RE> status of the last command executed.   And yes, explicitly saying what the
RE> script means (even the quite short scripts that make, usually, uses) really
RE> is the best way.

*sigh*.  what a pain.


RE>   | How would you have something run, then, that drops instantly dead in its
RE>   | tracks?
RE>
RE> I don't think I would, and I doubt anyone else would either.   However, if
RE> sh -e was truly implemented to simply have the shell exit, whenever any
RE> command that is run fails (which I think some implementations did, and
RE> approximates what csh does) then that would at least be consistent.

csh is, I hate to say, a straw man, since it executes *everything* in
immediate/line-mode rather than block mode.

RE>
RE> But then you no longer get to use && or || or if or anything after a while
RE> or ... in the script, as as soon as the conditional command fails, the script
RE> ends.  Useless, but at least consistent.

The funny thing is that I actually had the other end of a || at an if/then/fi
fail on me and cause my script to bomb out.  I was kind of astonished at
that one.

RE> It is when all the "except for..." stuff was added, to attempt to make "sh -e"
RE> useful, rather than useless, that everything started to get so hard to manage,
RE> and understand.   That kind of behaviour is usually a pretty good indicator
RE> that the underlying concept is simply the wrong thing to be attempting.

I disagree, but only for sake of convenience :-).

I would say that conditional evaluations should be exempt from earlier-
than-usual termination.  This means ||, &&, if/while/until loops.
It would not include ().  I mean, { ... ;} aren't included, why ()?

However, since I'm not on the committee, it's moot anyway and I'll just
have to work around it.

RE>   | Should you be required to jump through hoops to make that happen?
RE>
RE> yes, actually, if you really want that.   Most scripts on the other hand
RE> expect to exit only if particular commands fail - not any arbitrary command.

Hm, yes, I can see where the assumptions would be a really BAD idea.

RE> I write stuff like
RE>
RE> 	cd "$wherever" || exit 1
RE>
RE> all the time in my scripts - anything that might fail, and which would then
RE> cause the remainder of the script to be useless -- if the failing command won't
RE> print a suitable error already, it would be cmd || { echo "..." >&2; exit 1; }

Likewise.  I don't use the -e in scripts.  make(1), I guess, needs
to be changed to deal with this.

RE> kre


				--*greywolf;
--
Theorem #1:  There are several ways to create a quantum black hole.
    - Butter a piece of bread and tie it, buttered side up, to a cat's back.
    - Launder any number of matched pairs of socks.
    - Divide by zero.  Someone will disappear.  It might be your lucky day.