Arithmetic expansion and parameter expansion

Tim
$ 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?

cuonglm

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

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Bash: Arithmetic expansion, parameter expansion, and the comma operator

From Dev

Shell Arithmetic Expansion with Quotes

From Dev

Is a subscript to an indexed array an arithmetic expansion?

From Dev

test with arithmetic expansion (leading zero)

From Dev

How to apply parameter expansion on brace expansion (range)?

From Dev

Use parameter expansion to modify output of another expansion

From Dev

Parameter expansion (variable expansion) and quotes within quotes

From Dev

: and := inside a bash parameter expansion

From Dev

Parameter pack expansion fails

From Dev

Parameter Expansion With Python

From Dev

Parameter expansion in grep

From Dev

Parameter expansion on multiple variables

From Dev

Usage of ! in parameter expansion

From Dev

Parameter expansion question

From Dev

Parameter Expansion With Python

From Dev

Where is '/?' parameter expansion documented?

From Dev

Bash parameter expansion

From Dev

Shell parameter expansion on arrays

From Dev

Dynamic parameter expansion

From Dev

Zsh parameter expansion

From Dev

Bash Parameter expansion

From Dev

Parameter pack expansion questions

From Dev

Understand two examples using indirect expansion for variable expansion in arithmetic expressions

From Dev

Is arithmetic expansion related to IFS in some way?

From Dev

bash arithmetic expansion seems to be prone to injection attacks

From Dev

Can a parameter expansion work inside another parameter expansion?

From Dev

Simple parameter pack expansion: expected ';'

From Dev

file name parameter expansion bash

From Dev

C system() call parameter expansion