2
$ x=foo; foo=bar; bar=6; 

$ echo $x
foo

$ echo $((x))
6

why can the arithmetic expansion trace from variable x to its value foo, from variable foo to its value bar, and then from variable foo to its value 6, instead of stopping at the value foo of x?

Does it look like that arithmetic expansion applies eval indefinitely many times to parameter expansion of the variable x, until reaching an integer or nothing?

3

That's an extension of bash (and also zsh, ksh and its derivatives) to allow shell variable contain invalid integer constant to be reused in arithmetic expression.

From bash 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. The value of a variable is evaluated as an arithmetic expression when it is referenced, or when a variable which has been given the integer attribute using ‘declare -i’ is assigned a value. A null value evaluates to 0. A shell variable need not have its integer attribute turned on to be used in an expression.

So in your case, $((x)) first expanded x to foo, which is an invalid integer, so foo is reused as a variable name reference. Then foo was expanded to bar, the process above was repeated, until you got 6, which is an valid integer.


POSIX spec only stated that $((x)) and $(($x)) will return the same value only when x is a valid integer constant. It does not say anything about the case x is an invalid integer, so shell implementations is free to handle this situation.

The result can be varied with different shells.

zsh, ksh and its derivatives behave like bash above (and also busybox sh).

ash, dash raise error if x contain invalid integer

$ x=foo foo=bar bar=6 dash -c 'echo "$((x))"'
dash: 1: Illegal number: foo

yash leaves the variable as-is:

$ x=foo foo=bar bar=6 yash -c 'echo "$((x))"'
foo
  • Thanks. In "The value of a variable is evaluated as an arithmetic expression when it is referenced, or when a variable which has been given the integer attribute using ‘declare -i’ is assigned a value", what does "when a variable which has been given the integer attribute using ‘declare -i’ is assigned a value " mean? I don't understand why it uses "a variable" instead of "the variable" to refer to the same variable as "a variable" in "the value of a variable" at the beginning. – Tim Apr 24 '16 at 9:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.