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.