The operands of the numerical comparisons -eq
, -gt
, -lt
, -ge
, -le
and -ne
are taken as arithmetic expressions. With some limitation, they still need to be single shell words.
The behaviour of variable names in arithmetic expression is described in Shell Arithmetic:
Shell variables are allowed as operands; parameter expansion is performed before the expression is evaluated. Within an expression, shell variables may also be referenced by name without using the parameter expansion syntax. A shell variable that is null or unset evaluates to 0 when referenced by name without using the parameter expansion syntax.
and also:
The value of a variable is evaluated as an arithmetic expression when it is referenced
But I can't actually find the part of the documentation where it's said that the numeric comparisons take arithmetic expressions. It's not described in Conditional Constructs under [[
, nor is it described in Bash Conditional Expressions.
But, by experiment, it seems to work as said above.
So, stuff like this works:
a=6
[[ a -eq 6 ]] && echo y
[[ 1+2+3 -eq 6 ]] && echo y
[[ "1 + 2 + 3" -eq 6 ]] && echo y
this too (the value of the variable is evaluated):
b='1 + 2 + 3'
[[ b -eq 6 ]] && echo y
But this doesn't; it's not a single shell word when the [[ .. ]]
is parsed, so there's a syntax error in the conditional:
[[ 1 + 2 + 3 -eq 6 ]] && echo y
In other arithmetic contexts, there's no need for the expression to be without whitespace. This prints 999
, as the brackets unambiguously delimit the arithmetic expression in the index:
a[6]=999; echo ${a[1 + 2 + 3]}
On the other hand, the =
comparison is a pattern match, and doesn't involve arithmetic, nor the automatic variable expansion done in an arithmetic context (Conditional Constructs):
When the ==
and !=
operators are used, the string to the right of the operator is considered a pattern and matched according to the rules described below in Pattern Matching, as if the extglob shell option were enabled. The =
operator is identical to ==
.
So this is false since the strings are obviously different:
[[ "1 + 2 + 3" = 6 ]]
as is this, even though the numerical values are the same:
[[ 6 = 06 ]]
and here, too, the strings (x
and 6
) are compared, they're different:
x=6
[[ x = 6 ]]
This would expand the variable, though, so this is true:
x=6
[[ $x = 6 ]]
x=1
followed by[[ x -gt 2]]
? – nohillside Dec 03 '18 at 21:01