bug-bash
[Top][All Lists]
Advanced

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

Re: Possible bug in bash


From: Greg Wooledge
Subject: Re: Possible bug in bash
Date: Fri, 13 May 2022 23:27:50 -0400

On Fri, May 13, 2022 at 10:36:56PM -0400, Dale R. Worley wrote:
> Reading your message, I believe that the rule can be stated as follows,
> and I'd thank you to check it:  && and || have the same precedence, and
> they both "associate left".  So for example
>     x && yy || zz
> is equivalent (as a control structure) to
>     { x && yy ;} || zz

Not really.  Let's say you have a bunch of commands strung together like
this:

a && b || c && d || e && f || g

We start with the shell's command parser pointing to "a", which I'll
represent like this:

a && b || c && d || e && f || g
^

So, "a" is executed, and this sets the $? special parameter to some value,
either 0 or nonzero.  The parser moves to the right and sees "&& b":

a && b || c && d || e && f || g
  ^^^^

So it checks $?.  If $? is 0, then b will be executed.  Otherwise, the
parser will keep reading to the right.  Next it sees "|| c":

a && b || c && d || e && f || g
       ^^^^

If $? is nonzero (either from "a" or from "b"), then "c" will be executed.
Otherwise, the parser keeps reading to the right:

a && b || c && d || e && f || g
            ^^^^

And so on, until the entire line has been processed.  Each simple command
in the line is either executed, or not, depending on the current value
of $? and the operator which precedes it.

That's why this has no equivalence to a regular "if/then/else" command.
The implementation is just entirely different.

Here's an actual example:

unicorn:~$ false && true || true && echo a || false && echo b
a
b

The first "false" is executed no matter what; this sets $? to 1.  The
parser looks at "&& true" and skips it because $? is nonzero.  So it
looks at "|| true", and runs that because $? is nonzero.  Now $? is 0.
Next up is "&& echo a", and since $? is 0, bash runs that echo.  This
sets $? to 0 (because the echo succeeded), so "|| false" is skipped.
The parser finally ends on "&& echo b", and since $? is 0, that echo
is also executed.

In real life, there is no reason to write code like this.  It's horrible
and confusing.  Just don't do it.



reply via email to

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