Discussion:
[Help-bash] && precedence
Russell Shaw
2017-08-09 11:35:28 UTC
Permalink
Hi,
When i do:

true || echo hi

there is no "hi" as expected


when i do:

true || true && echo hi

i get "hi" echoed. Why does "true && echo hi" get evaluated?
Matthew Cengia
2017-08-09 12:00:13 UTC
Permalink
foo && bar || baz is not equivalent to 'if foo; then bar; else baz; fi'.
In the former case, baz will happen if *either* foo *or* bar return false.
In the latter case, baz will only trigger if foo returns false, regardless
of the exit code for bar. See http://mywiki.wooledge.org/BashPitfalls
Hi,
true || echo hi
there is no "hi" as expected
true || true && echo hi
i get "hi" echoed. Why does "true && echo hi" get evaluated?
--
Regards,
Matthew Cengia
Matthew Cengia
2017-08-09 12:01:21 UTC
Permalink
Oh, I misread your question; you have the tests in the reverse order. I'm
not 100% sure about this one; sorry.
Post by Matthew Cengia
foo && bar || baz is not equivalent to 'if foo; then bar; else baz; fi'.
In the former case, baz will happen if *either* foo *or* bar return false.
In the latter case, baz will only trigger if foo returns false, regardless
of the exit code for bar. See http://mywiki.wooledge.org/BashPitfalls
Hi,
true || echo hi
there is no "hi" as expected
true || true && echo hi
i get "hi" echoed. Why does "true && echo hi" get evaluated?
--
Regards,
Matthew Cengia
--
Regards,
Matthew Cengia
Matthew Cengia
2017-08-09 12:05:13 UTC
Permalink
I think it's an order of operation thing. Look what happens when I use
group commands in braces to force order of operation:

***@isis:tmp$ { true || true ;} && echo hi
hi
***@isis:tmp$ true || { true && echo hi ;}
***@isis:tmp$

(Sorry for the multiple messages, folks; I should've thought harder with my
first message!)
Post by Matthew Cengia
Oh, I misread your question; you have the tests in the reverse order. I'm
not 100% sure about this one; sorry.
foo && bar || baz is not equivalent to 'if foo; then bar; else baz;
fi'. In the former case, baz will happen if *either* foo *or* bar return
false. In the latter case, baz will only trigger if foo returns false,
regardless of the exit code for bar. See http://mywiki.wooledge.org/Bas
hPitfalls
Hi,
true || echo hi
there is no "hi" as expected
true || true && echo hi
i get "hi" echoed. Why does "true && echo hi" get evaluated?
--
Regards,
Matthew Cengia
--
Regards,
Matthew Cengia
--
Regards,
Matthew Cengia
John McKown
2017-08-09 12:07:31 UTC
Permalink
Post by Russell Shaw
Hi,
true || echo hi
there is no "hi" as expected
true || true && echo hi
i get "hi" echoed. Why does "true && echo hi" get evaluated?
​What you are expecting can be coded like: true || { true && echo hi ; }

I think what you are expecting​ is like in arithmetic where || is like +
and && is like * so that the "true && echo hi" is a "single" operand to the
"||" operator. But I don't think that BASH does it that way. To expand a bit
the first "true" is run and $? is set to 0. The || is evaluated and says
"no, don't execute the next command because $? is 0", so the second "true"
is not run. The && is then evaluated and $? is still set to 0 from the
first true and so the "echo hi" is run.
--
Veni, Vidi, VISA: I came, I saw, I did a little shopping.

Maranatha! <><
John McKown
Pierre Gaston
2017-08-09 12:10:13 UTC
Permalink
Post by Russell Shaw
Hi,
true || echo hi
there is no "hi" as expected
true || true && echo hi
i get "hi" echoed. Why does "true && echo hi" get evaluated?
The manual says:
"Of these list operators, && and ││ have equal precedence"

Take care that you also have && and || inside [[ ]] where they do not
Russell Shaw
2017-08-09 12:48:29 UTC
Permalink
Post by Pierre Gaston
Post by Russell Shaw
Hi,
true || echo hi
there is no "hi" as expected
true || true && echo hi
i get "hi" echoed. Why does "true && echo hi" get evaluated?
"Of these list operators, && and ││ have equal precedence"
Take care that you also have && and || inside [[ ]] where they do not
From the horses mouth:

<http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html>

2.9.3 Lists

An AND-OR list is a sequence of one or more pipelines separated by the operators
"&&" and "||" .

A list is a sequence of one or more AND-OR lists separated by the operators ';'
and '&' and optionally terminated by ';', '&', or <newline>.

The operators "&&" and "||" shall have equal precedence and shall be evaluated
with left associativity. For example, both of the following commands write
solely bar to standard output:

false && echo foo || echo bar
true || echo foo && echo bar

--------------

I think what happens is this.

With equal precedence and left associativity, the parser shifts in a Simple
command and evaluates it only if it is the first command, or the previous op was
|| and the "running" shell status is "fail", or if the previous op was && and
the "running" shell status is "success". It shifts all the and-or list Simple
commands through to the end.
Russell Shaw
2017-08-09 14:35:12 UTC
Permalink
Post by Russell Shaw
Post by Pierre Gaston
Post by Russell Shaw
Hi,
true || echo hi
there is no "hi" as expected
true || true && echo hi
i get "hi" echoed. Why does "true && echo hi" get evaluated?
"Of these list operators, && and ││ have equal precedence"
Take care that you also have && and || inside [[ ]] where they do not
<http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html>
2.9.3 Lists
An AND-OR list is a sequence of one or more pipelines separated by the operators
"&&" and "||" .
A list is a sequence of one or more AND-OR lists separated by the operators ';'
and '&' and optionally terminated by ';', '&', or <newline>.
The operators "&&" and "||" shall have equal precedence and shall be evaluated
with left associativity. For example, both of the following commands write
false && echo foo || echo bar
true || echo foo && echo bar
--------------
I think what happens is this.
With equal precedence and left associativity, the parser shifts in a Simple
command and evaluates it only if it is the first command, or the previous op was
|| and the "running" shell status is "fail", or if the previous op was && and
the "running" shell status is "success". It shifts all the and-or list Simple
commands through to the end.
Correction: "Simple command" should have been "Pipeline".
DJ Mills
2017-08-09 17:42:11 UTC
Permalink
Post by Russell Shaw
Post by Russell Shaw
Post by Pierre Gaston
Hi,
Post by Russell Shaw
true || echo hi
there is no "hi" as expected
true || true && echo hi
i get "hi" echoed. Why does "true && echo hi" get evaluated?
"Of these list operators, && and ││ have equal precedence"
Take care that you also have && and || inside [[ ]] where they do not
<http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html
2.9.3 Lists
An AND-OR list is a sequence of one or more pipelines separated by the operators
"&&" and "||" .
A list is a sequence of one or more AND-OR lists separated by the operators ';'
and '&' and optionally terminated by ';', '&', or <newline>.
The operators "&&" and "||" shall have equal precedence and shall be evaluated
with left associativity. For example, both of the following commands write
false && echo foo || echo bar
true || echo foo && echo bar
--------------
I think what happens is this.
With equal precedence and left associativity, the parser shifts in a Simple
command and evaluates it only if it is the first command, or the previous op was
|| and the "running" shell status is "fail", or if the previous op was && and
the "running" shell status is "success". It shifts all the and-or list Simple
commands through to the end.
Correction: "Simple command" should have been "Pipeline".
Why wouldn't you just use if statements anyway? Chains of && and || are
horrific for readability and troubleshooting
Russell Shaw
2017-08-09 23:36:55 UTC
Permalink
...
Post by DJ Mills
Post by Russell Shaw
Correction: "Simple command" should have been "Pipeline".
Why wouldn't you just use if statements anyway? Chains of && and || are
horrific for readability and troubleshooting
Because i was writing C code that executes shell-like statement strings, so had
to get the semantics right.
Russell Shaw
2017-08-12 07:03:52 UTC
Permalink
I found answers here:

<https://unix.stackexchange.com/questions/88850/precedence-of-the-shell-logical-operators>
Chet Ramey
2017-08-09 23:49:29 UTC
Permalink
Post by Russell Shaw
<http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html>
2.9.3 Lists
An AND-OR list is a sequence of one or more pipelines separated by the
operators "&&" and "||" .
A list is a sequence of one or more AND-OR lists separated by the operators
';' and '&' and optionally terminated by ';', '&', or <newline>.
The operators "&&" and "||" shall have equal precedence and shall be
evaluated with left associativity. For example, both of the following
false && echo foo || echo bar
true || echo foo && echo bar
--------------
I think what happens is this.
It gets parsed as if it were entered as '{ true || true; } && echo hi'.
Left associativity, equal precedence.
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU ***@case.edu http://cnswww.cns.cwru.edu/~chet/
Loading...