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
然后我修改了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")
为什么出现此错误,任何建议都会受到欢迎!
答案 0 :(得分:6)
此:
key="index";
arr[$key]="val"
echo ${arr[${key}]}
只有出现才能正常工作。由于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]}
所有echo
语句都打印val
。由于索引被视为算术表达式,因此它可以引用带有或不带$index
前缀的变量(在本例中为$
) - 即使它是带引号的字符串。
在代码中,您从未将值分配给$index
,${arr[${key}]}
会扩展为${arr[index]}
,相当于${arr[$index]}
,会被视为(默认情况下)等同于${arr[0]}
。
(如果您有set -o nounset
,则对未设置变量的引用将被视为错误,您的代码将生成错误消息。)
你的第二块代码:
key="index.index";
arr[$key]="val"
echo ${arr[${key}]}
无效,因为index.index
不是有效的变量名称 - 即使您可能只是将其视为用作数组索引的字符串。
如果希望arr
允许任意字符串作为索引,则它必须是关联数组。您可以通过分配非关联数组(或使用declare -a
)来创建非关联数组,但只能使用declare -A
创建关联数组。
在版本4中将关联数组添加到bash中。如果您使用的是早期版本的bash,则不支持declare -A
。您需要升级到更新的bash,编写一些笨拙的替代品,或使用支持关联数组的语言,如Awk,Python或Perl。
添加declare -A arr
(如user000001's answer建议的那样)应解决问题(如果你有bash 4),但了解原始代码实际在做什么(或者更确切地说没有做)是有益的。< / p>
(顺便说一下,谢谢你提出这个问题;我在撰写这个答案时学到了很多东西。)
答案 1 :(得分:5)
使用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
答案 2 :(得分:1)
此行为因BASH版本而异。较旧的BASH版本仅允许非负整数作为数组中的键。
请注意,BASH中的变量名称不允许dot/period
。
有关BASH中允许的字符的更多详细信息,请参阅此问答:Allowed characters in linux environment variable names
修改强>
(非常感谢@chepner的这个附录)
常规数组(非关联数组)仅由整数索引。用作方括号之间索引的任何表达式都被视为算术表达式。 $ key扩展为index,然后将其视为(未设置)变量,扩展为0.如果为索引分配了值3,则为${array[$key]} -> ${array[index]} -> ${array[3]}
。这是一种隐式间接参数扩展