With only two boolean terms, both are equivalent.
[[ -z $a || -z $b ]]
being a single statement it might be slightly more performant.
With a mixture of “and” and “or” operators, there is a difference: inside [[ … ]]
, &&
has precedence over ||
(like in C and many other languages), but outside [[ … ]]
, a chain of &&
and ||
is evaluated from left to right with equal precedence.
#!/usr/bin/env bash
printf %s\\n '[[ $a -eq 1 && $b -eq 1 || $c -eq 1 ]]'
for a in 0 1; do
for b in 0 1; do
for c in 0 1; do
[[ $a -eq 1 && $b -eq 1 || $c -eq 1 ]]
printf '%d AND %d OR %d = %d\n' $a $b $c $((!$?))
done
done
done
printf '\n%s\n' '[[ $a -eq 1 ]] && { [[ $b -eq 1 ]] || [[ $c -eq 1 ]];}'
for a in 0 1; do
for b in 0 1; do
for c in 0 1; do
[[ $a -eq 1 ]] && { [[ $b -eq 1 ]] || [[ $c -eq 1 ]];}
printf '%d AND (%d OR %d) = %d\n' $a $b $c $((!$?))
done
done
done
Output:
[[ $a -eq 1 && $b -eq 1 || $c -eq 1 ]]
0 AND 0 OR 0 = 0
0 AND 0 OR 1 = 1
0 AND 1 OR 0 = 0
0 AND 1 OR 1 = 1
1 AND 0 OR 0 = 0
1 AND 0 OR 1 = 1
1 AND 1 OR 0 = 1
1 AND 1 OR 1 = 1
[[ $a -eq 1 ]] && { [[ $b -eq 1 ]] || [[ $c -eq 1 ]];}
0 AND (0 OR 0) = 0
0 AND (0 OR 1) = 0
0 AND (1 OR 0) = 0
0 AND (1 OR 1) = 0
1 AND (0 OR 0) = 0
1 AND (0 OR 1) = 1
1 AND (1 OR 0) = 1
1 AND (1 OR 1) = 1