"invalid arithmetic operator" in the shell

cat test.sh

#!/bin/bash key="index"; arr[$key]="val" echo ${arr[${key}]} 

/ bin / bash -x test.sh

 + key=index + arr[$key]=val + echo val val 

then I modify test.sh:

 #!/bin/bash key="index.index"; arr[$key]="val" echo ${arr[${key}]} 

/ bin / bash -x test.sh

 + key=index.index + arr[$key]=val test.sh: line 3: index.index: syntax error: invalid arithmetic operator (error token is ".index") test.sh: line 4: index.index: syntax error: invalid arithmetic operator (error token is ".index") 

why this error appears, any suggestion will be appreciated!

+4
source share
3 answers

Declare the array variable as an associative array with declare -A arr .

 $ cat test.sh #!/bin/bash set -x declare -A arr key="index.index"; arr["$key"]="val" echo "${arr["${key}"]}" $ ./test.sh + declare -A arr + key=index.index + arr["$key"]=val + echo val val 
+4
source

It:

 key="index"; arr[$key]="val" echo ${arr[${key}]} 

only works. Since arr is a regular array, not an associative array, it can only be indexed with non-negative integer values.

Consider this valid code:

 index=42 key="index" arr[$key]="val" echo ${arr[42]} echo ${arr[index]} echo ${arr[$index]} echo ${arr['index']} echo ${arr["index"]} echo ${arr[\index]} 

All echo statements print val . Since an index is considered an arithmetic expression, it can refer to a variable (in this case, $index ) either with the $ prefix or without it, even if it is a quoted string.

In your code, where you never assigned a value to $index , ${arr[${key}]} expands to ${arr[index]} , which is equivalent to the ${arr[$index]} that is being processed (by default) as equivalent to ${arr[0]} .

(If you have set -o nounset , then references to undefined variables are treated as errors, and your code will generate an error message.)

Second code snippet:

 key="index.index"; arr[$key]="val" echo ${arr[${key}]} 

incorrect since index.index not a valid variable name, although you probably meant that it was just a string used as the index of an array.

If you want arr to allow arbitrary strings as indices, it must be an associative array. You can create a non-associative array by simply assigning it (or using declare -a ), but an associative array can only be created using declare -a .

Associative arrays were added to bash in version 4. If you are using an earlier version of bash, declare -a not supported. You will need to upgrade to a new bash, copy some awkward alternative, or use a language that supports associative arrays like Awk, Python or Perl.

Adding declare -A arr (as user000001 the answer suggests) should solve the problem (if you have bash 4), but it is instructive to understand what your source code is (or rather does not).

(By the way, thanks for that, I learned a lot when I wrote this answer.)

+5
source

This behavior is dependent on the version of BASH. Older versions of BASH allow the use of non-negative integers as keys in arrays.

Note that dot/period not allowed in the variable name in BASH.

More on valid characters in BASH: See this Q & A Allowed characters in linux environment variable names

EDIT:

(Many thanks to @chepner for this add-on)

Regular arrays (not an associative array) are indexed only by an integer. Any expression used as an index between square brackets is treated as an arithmetic expression. $ key expands to an index, which is then treated as a (undefined) variable that expands to 0. If you specify a value, say 3 for the index, then ${array[$key]} -> ${array[index]} -> ${array[3]} . This is a type of implicit extension of indirect parameters.

+1
source

Source: https://habr.com/ru/post/1497215/


All Articles