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.