Precedence of the shell logical operators &&, ||

Martin Vegter

I am trying to understand how the logical operator precedence works in bash. For example, I would have expected, that the following command does not echo anything.

true || echo aaa && echo bbb

However, contrary to my expectation, bbb gets printed.

Can somebody please explain, how can I make sense of compounded && and || operators in bash?

Joseph R.

In many computer languages, operators with the same precedence are left-associative. That is, in the absence of grouping structures, leftmost operations are executed first. Bash is no exception to this rule.

This is important because, in Bash, && and || have the same precedence.

So what happens in your example is that the leftmost operation (||) is carried out first:

true || echo aaa

Since true is obviously true, the || operator short-circuits and the whole statement is considered true without the need to evaluate echo aaa as you would expect. Now it remains to do the rightmost operation:

(...) && echo bbb

Since the first operation evaluated to true (i.e. had a 0 exit status), it's as if you're executing

true && echo bbb

so the && will not short-circuit, which is why you see bbb echoed.

You would get the same behavior with

false && echo aaa || echo bbb

Notes based on the comments

  • You should note that the left-associativity rule is only followed when both operators have the same precedence. This is not the case when you use these operators in conjunction with keywords such as [[...]] or ((...)) or use the -o and -a operators as arguments to the test or [ commands. In such cases, AND (&& or -a) takes precedence over OR (|| or -o). Thanks to Stephane Chazelas' comment for clarifying this point.
  • It seems that in C and C-like languages && has higher precedence than || which is probably why you expected your original construct to behave like

    true || (echo aaa && echo bbb). 
    

    This is not the case with Bash, however, in which both operators have the same precedence, which is why Bash parses your expression using the left-associativity rule. Thanks to Kevin's comment for bringing this up.

  • There might also be cases where all 3 expressions are evaluated. If the first command returns a non-zero exit status, the || won't short circuit and goes on to execute the second command. If the second command returns with a zero exit status, then the && won't short-circuit as well and the third command will be executed. Thanks to Ignacio Vazquez-Abrams' comment for bringing this up.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Related Related

HotTag

Archive