Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"invalid arithmetic operator" in 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 the 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 appreciate!

like image 556
Tim Avatar asked Aug 15 '13 10:08

Tim


People also ask

Which of the following is not a arithmetic operator?

& operator is not an arithmetic operator The basic arithmetic operations are addition, subtraction, multiplication, and division. There are more arithmetic operators like exponentiation, modulus operations, increment, decrement, etc. * - Multiplication operator. So, And operator is not an arithmetic operator.


1 Answers

This:

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

only appears to work. Since arr is an ordinary array, not an associative array, it can only be indexed by 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 the echo statements print val. Since the index is treated as an arithmetic expression, it can refer to a variable (in this case, $index) either with or without the $ prefix -- even if it's a quoted string.

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

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

Your second chunk of code:

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

is invalid because index.index is not a valid variable name -- even though you probably meant it to be just a string used as an array index.

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

Associative arrays were added to bash in version 4. If you're using an earlier version of bash, declare -A is not supported. You'll need to upgrade to a newer bash, code up some clumsy alternative, or use a language that does support associative arrays, like Awk, Python, or Perl.

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

(BTW, thanks for asking this; I learned a lot as I was composing this answer.)

like image 164
Keith Thompson Avatar answered Sep 30 '22 15:09

Keith Thompson