bash – Understanding Indirect Expansion for Variable Expansion in Arithmetic Expressions

bash

Stéphane Chazelas gave two examples in The value of a variable is evaluated as an arithmetic expression when it is referenced, or assigned

$ a=1+1; echo "$((a * 3)) $(($a * 3))"
6 4

$ a=a=b++ b=1 bash -c 'echo "$((++a)) $b"'
2 2

I understand there is indirect expansion for variable expansion in arithmetic expressions. But I can't figure out

  • how do a and $a in the first example result in such a difference?
    My confusion comes from that in arithmetic expressions, parameter expansion of a variable doesn't need ${}, just write the variable directly.

  • how is the arithmetic expression in the second example evaluated?

Thanks.

Best Answer

Parameter expansion isn’t the same as arithmetic evaluation.

In an arithmetic expression, a text string such as a is interpreted as a variable name, and the value of that variable is processed as an arithmetic expression itself, and the result used in the containing arithmetic expression. Thus

$((a * 3))

causes the value of the variable a, 1+1, to be evaluated as an arithmetic expression, yielding 2, and the whole expression becomes $((2 * 3)), i.e. 6.

In the same context, $a is replaced with the value of a as-is, in an earlier phase (this is parameter expansion); so

$(($a * 3))

becomes $((1+1 * 3)), which is 4 following the usual precedence rules.

In the second example, $((++a)) is processed before $b (processing takes place from left to right). The arithmetic expression causes a to be evaluated as an arithmetic expression itself, as above; the value of a is a=b++, which when evaluated, assigns the value of b (itself evaluated as an arithmetic expression) to a, then increments b. Thus after evaluating a, b is 2 and a is 1. Evaluating $((++a)) increments a and returns its value, which is now 2. $b is just replaced with the value of b, 2 as well. After the quoted argument to echo is processed, the echo is run with 2 2 as its sole argument, producing the output you saw.

Related Question