The POSIX spec states with regard to Arithmetic Expansion that
[i]f the shell variable x contains a value that forms a valid integer constant, optionally including a leading plus or minus sign, then the arithmetic expansions "$((x))" and "$(($x))" shall return the same value.
Which is a reasonable shortcut and cleans up complicated expressions rather nicely.
bash (versions 3.2.25(1)-release
from CentOS 5 and 4.3.33(1)-release
from debian unstable) as well as ksh (Version AJM 93t+ 2010-06-21
from CentOS 5) all seem to go one step farther then that however.
They all seem to recursively expand variables encountered in arithmetic expansion (and numeric contexts in [[
resulting from using the numeric operators).
Specifically:
$ set -x
$ bar=5
+ bar=5
$ foo=bar
+ foo=bar
$ [ foo -gt 4 ]; echo $?
+ '[' foo -gt 4 ']'
-bash: [: foo: integer expression expected
+ echo 2
2
$ [[ foo -gt 4 ]]; echo $?
+ [[ foo -gt 4 ]]
+ echo 0
0
$ [[ foo -eq 0 ]]; echo $?
+ [[ foo -eq 0 ]]
+ echo 1
1
$ [[ foo -eq 5 ]]; echo $?
+ [[ foo -eq 5 ]]
+ echo 0
0
$ (( foo == bar )); echo $?
+ (( foo == bar ))
+ echo 0
0
$ (( foo == 1 )); echo $?
+ (( foo == 1 ))
+ echo 1
1
Where does this behavior come from and why would it ever be desirable?
It makes using [[
in place of [
explicitly less safe when used with numeric operators because invalid values and typographical errors go from being script errors to being silently valid (but likely erroneous) tests.
Edit: As a side question if anyone happens to know when this "feature" was added to bash/etc. I would be interested in knowing that as well.