bug-bash
[Top][All Lists]
Advanced

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

Re: Syntax Question...


From: Ken Irving
Subject: Re: Syntax Question...
Date: Tue, 16 Aug 2011 15:49:22 -0800
User-agent: Mutt/1.5.20 (2009-06-14)

On Tue, Aug 16, 2011 at 03:41:19PM -0700, Linda Walsh wrote:
> Ken Irving wrote:
> >It seems to me that there are real bugs in applying set -e that can only
> >be fixed by handling more special cases in the bash code,and those cases
> >may vary for different scripts.
> 
> >[snip]
> >    set ...
> >    -e  The shell does not exit if the command that fails is part of the
> >        command list immediately  following  a while or until keyword,
> >        part of the test following the if or elif reserved words,
> >        part of any command executed in a && or || list except the
> >        command following the final && or ||, any command in a pipeline
> >        but the  last,  or  if  the  command's return  value  is being
> >        inverted with !
> >A constructive contribution might be made by seeing if you can add your
> >special cases to that list, even better if you can help by identifying
> >where it might be done in the code.
> -----
> ARRGGG...these were not special cases, they were has bash normally
> worked in in it's non-posix mode SINCE they were created! (3.0 and
> up through 4.0).
> 
> ****4.1 breaks the previous standard.**** -- it's not compatible with
> bash 3.0 or 4.0 in this regard
> 
> Example:  from 2 different linux systems, one w/bash 4.0 and one w/
> the broken 4.1 (which will likely be reverted to 4.0 very soon if 4.1
> doesn't get a fix)..
> 
> Here is a working 'bash (4.0) vs.  current, below:
> 
>    Astarte:/tmp> rpm -q bash
>    bash-4.0-18.4.1.i586
>    Astarte:/tmp> ( set -e ; ((a=0)); echo "are we here?"  )
>    are we here?
>    Astarte:/tmp>
> 
> Now for the current behavior:
> 
>    Ishtar:/tmp> rpm -q bash
>    bash-4.1-20.25.1.x86_64
>    Ishtar:/tmp> ( set -e ; ((a=0)); echo "are we here?" )
>    Ishtar:/tmp>
> 
> ----
> You see the difference?   In 4.0, the assignment didn't cause
> an errexit. -- ((a=0)) has NEVER cause an errexit since it

Please; ((a=0)) is documented to return a non-zero value under the
condition that it evaluates to 0.  That's what it's for.  It is *not* an
'errexit' or an error of any sort,  it's just its exit value.  That set
-e trips on that is exactly as it is documented to do, and just like
it would've done under the other conditions mentioned in the manpage if
code hadn't been added to specially handle those cases.

Unless (()) and let show up in the description for the set -e exceptions, 
it seems to me that it's working correctly now, and maybe it wasn't before.

> was introduced in bash 3.x[0?]    This is the now broken behavior
> and it was done to make one of bash's extended features compatible
> with POSIX -- which is a very BAD reason, as Bash has a posix mode
> for that -- and that POSIX mode changes shouldn't be
> contaminating the BASH-extended set.

Yes, we've heard all that before, several times. But the facts remain.
let and (()) are commands (with useful side effects, if you use them
correctly), set -e exits on non-zero exit values, etc., etc..

> I'm not asking for something "new", I'm asking for compatibility with
> the versions 3.0 -> 4.0

And I think it's clear that that's probably not going to happen, as the
way it works now is consistent and in accordance with the manual.

> Here's the quote from 4.0 on set -e:

(Also quoted above.)

> Note the above -- says it will exit on a "pipeline".....
> as 'let' and '(())' did not take or accept I/O, they wouldn't
> normally be considered part of a pipeline -- and Greg has
> mentioned that ((1)), is a 'complex' command not a simple command
> (but it can't be used as part of a pipeline...)

That's a new argument, I think, and pretty weak.

    $ ls | ((a=1)); echo $?
    0

Just because a command ignores stdin doesn't mean it can't be used
in a pipeline.

    $ bash -c 'set -e; ls | ((a=1)); echo x $?'; echo y $? 
    x 0
    y 0
    $ bash -c 'set -e; ls | ((a=0)); echo x $?'; echo y $?
    y 1
    $ bash -c 'set -e; ls | ((a=0)) | cat; echo x $?'; echo y $?
    x 0
    y 0

Here the (()) is not at the end of the pipeline, so set -e is not triggered.

I don't see how this is not the correct behavior.

I suspect the warnings against using set -e are in part resulting from threads
such as this one, where folks get tripped up on some special case.  Maybe it's
possible to add yet another exceptional condition to keep set -e at bay, but 
you might consider trying another approach.  Good luck!

Ken




reply via email to

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