These days I am reading the book 'Advanced Bash-Scripting Guide' and I got confused about '&&' and '-a'.
The related part was here:
- [ 1 -eq 1 ] && [ -n "`echo true 1>&2`" ] # true
- [ 1 -eq 2 ] && [ -n "`echo true 1>&2`" ] # (no output)
- # ^^^^^^^ False condition. So far, everything as expected.
- # However ...
- [ 1 -eq 2 -a -n "`echo true 1>&2`" ] # true
- # ^^^^^^^ False condition. So, why "true" output?
- # Is it because both condition clauses within brackets evaluate?
- [[ 1 -eq 2 && -n "`echo true 1>&2`" ]] # (no output)
- # No, that's not it.
- # Apparently && and || "short-circuit" while -a and -o do not.
The last line explained the reason, but I wanted to find more evidences from the BASH manual and I got it.
- For && and ||:
- Expressions may be combined using the following operators, listed in decreasing order of precedence:
- ( expression )
- Returns the value of expression. This may be used to override the normal precedence of operators.
- ! expression
- True if expression is false.
- expression1 && expression2
- True if both expression1 and expression2 are true.
- expression1 || expression2
- True if either expression1 or expression2 is true.
- The && and || operators do not evaluate expression2 if the value of expression1 is sufficient to determine the return value of the entire condi-
- tional expression.
- For -a and -o:
- Expressions may be combined using the following operators, listed in decreasing order of precedence. The evaluation depends on the number of
- arguments; see below. Operator precedence is used when there are five or more arguments.
- ! expr True if expr is false.
- ( expr )
- Returns the value of expr. This may be used to override the normal precedence of operators.
- expr1 -a expr2
- True if both expr1 and expr2 are true.
- expr1 -o expr2
- True if either expr1 or expr2 is true.
- test and [ evaluate conditional expressions using a set of rules based on the number of arguments.
- 0 arguments
- The expression is false.
- 1 argument
- The expression is true if and only if the argument is not null.
- 2 arguments
- If the first argument is !, the expression is true if and only if the second argument is null. If the first argument is one of the unary
- conditional operators listed above under CONDITIONAL EXPRESSIONS, the expression is true if the unary test is true. If the first argument
- is not a valid unary conditional operator, the expression is false.
- 3 arguments
- The following conditions are applied in the order listed. If the second argument is one of the binary conditional operators listed above
- under CONDITIONAL EXPRESSIONS, the result of the expression is the result of the binary test using the first and third arguments as oper‐
- ands. The -a and -o operators are considered binary operators when there are three arguments. If the first argument is !, the value is
- the negation of the two-argument test using the second and third arguments. If the first argument is exactly ( and the third argument is
- exactly ), the result is the one-argument test of the second argument. Otherwise, the expression is false.
- 4 arguments
- If the first argument is !, the result is the negation of the three-argument expression composed of the remaining arguments. Otherwise,
- the expression is parsed and evaluated according to precedence using the rules listed above.
- 5 or more arguments
- The expression is parsed and evaluated according to precedence using the rules listed above.
So for '-a' and '-o', both sides will ALWAYS be executed.