[Top][All Lists]

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

Re: Incompatibility with POSIX 2008--- /bin/sh -e?

From: Paul Smith
Subject: Re: Incompatibility with POSIX 2008--- /bin/sh -e?
Date: Tue, 09 Jun 2009 23:42:33 -0400

On Tue, 2009-06-09 at 23:12 -0400, David Boyce wrote:
> I vote for the obvious .POSIX fix. Changing it unequivocally would
> break a lot of makefiles, IMHO, and in mysterious ways, because
> programming with -e is an acquired skill and not something most people
> think about. Just for instance, an attempt at defensive programming
> such as:
>     test -f foo && rm -f foo
> will backfire as the shell aborts before the &&. In fact all uses of
> && with -e are bad.

I'm not saying that the .POSIX method is not the right way to go, but I
don't understand your example here, since obviously if the test is false
then you wouldn't run the rm anyway.  I think you really meant something
like this:

        test -f foo && rm -f foo ; echo hi

thinking that with -e we would exit immediately if the test failed and
the "echo hi" would not be invoked.  But that's not how -e works; from
the POSIX spec:

                When this option is on, if a simple command fails for
                any of the reasons listed in Consequences of Shell
                Errors or returns an exit status value >0, and is not
                part of the compound list following a while, until, or
                if keyword, and is not a part of an AND or OR list, and
                is not a pipeline preceded by the ! reserved word, then
                the shell shall immediately exit.

Note the second half of this sentence.

> Similarly, the common idiom
>     some-command
>     if [ $? -ne 0 ]; then
>         (work around the problem)
>     fi
> will not work as designed.

This is definitely true, although this common form works fine:

        if ! some-command; then
                (work around the problem)

I guess if you still care about ridiculously old shells then this is a
problem as not all of them supported the "!" operator; you'd have to do
something like:

        if some-command; then
                : success
                (work around the problem)

Of course you can always disable -e (by adding set +e to your command
scripts), just as people who want it in GNU make currently enable it.

I too was pretty surprised when I saw this change, since it seems
counter-productive for a standard to change such a fundamental feature
in a new version like that.  In the Change History they say:

        Austin Group Interpretation 1003.1-2001 #131 is applied,
        changing the Makefile Execution section.

Which I can only take to mean that way back in 2001 or before they
realized that the text of the standard had a big "oops" in it, where
they always meant to have make use -e but got the text of the standard

Still, I'm irked that, after leaving so many things "undefined" because
different versions of make implemented them in different ways, they'd
accept this change to the standard rather than doing something else that
would allow GNU make (arguably the single most widely used version of
make) to continue to be compliant.

 Paul D. Smith <address@hidden>          Find some GNU make tips at:            
 "Please remain calm...I may be mad, but I am a professional." --Mad Scientist

reply via email to

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