shell中的"无效算术运算符"

Tim*_*Tim 5 unix linux bash shell

猫test.sh

#!/bin/bash
key="index";
arr[$key]="val"
echo ${arr[${key}]}
Run Code Online (Sandbox Code Playgroud)

/ bin/bash-x test.sh

+ key=index
+ arr[$key]=val
+ echo val
val
Run Code Online (Sandbox Code Playgroud)

然后我修改test.sh:

#!/bin/bash
key="index.index";
arr[$key]="val"
echo ${arr[${key}]}
Run Code Online (Sandbox Code Playgroud)

/ 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")
Run Code Online (Sandbox Code Playgroud)

为什么会出现此错误,任何建议都会受到欢迎!

Kei*_*son 7

这个:

key="index";
arr[$key]="val"
echo ${arr[${key}]}
Run Code Online (Sandbox Code Playgroud)

似乎只有工作.由于arr是普通数组,而不是关联数组,因此只能通过非负整数值进行索引.

考虑这个有效的代码:

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]}
Run Code Online (Sandbox Code Playgroud)

所有echo声明都打印出来val.由于索引被视为算术表达式,因此它可以引用$index带有或不带$前缀的变量(在这种情况下)- 即使它是带引号的字符串.

在您从未为其分配值的代码中$index,${arr[${key}]}展开${arr[index]}为等同于${arr[$index]}(默认情况下)等效于的代码${arr[0]}.

(如果有set -o nounset,则对未设置变量的引用被视为错误,并且您的代码将产生错误消息.)

你的第二块代码:

key="index.index";
arr[$key]="val"
echo ${arr[${key}]}
Run Code Online (Sandbox Code Playgroud)

是无效的,因为index.index它不是一个有效的变量名 - 即使你可能只是一个用作数组索引的字符串.

如果要arr允许任意字符串作为索引,则它必须是关联数组.您可以通过分配(或使用declare -a)来创建非关联数组,但只能使用关联数组创建declare -A.

在版本4中将关联数组添加到bash中.如果您使用的是早期版本的bash,declare -A则不支持.您需要升级到更新的bash,编写一些笨拙的替代品,或使用支持关联数组的语言,如Awk,Python或Perl.

添加declare -A arr(如user000001的答案所示)应解决问题(如果你有bash 4),但理解你的原始代码实际在做什么(或者更确切地说没有做)是有益的.

(顺便说一下,谢谢你提出这个问题;我在学习这个答案时学到了很多东西.)


use*_*001 6

将数组变量声明为关联数组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
Run Code Online (Sandbox Code Playgroud)

  • 值得注意的是,之前,字符串"index"在用作索引时被视为未设置变量,因此评估为0. (5认同)