bash shell中的“无效算术运算符”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18250857/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
"invalid arithmetic operator" in shell
提问by Tim
cat test.sh
猫测试.sh
#!/bin/bash
key="index";
arr[$key]="val"
echo ${arr[${key}]}
/bin/bash-x test.sh
/bin/bash-x test.sh
+ key=index
+ arr[$key]=val
+ echo val
val
then I modify the test.sh:
然后我修改test.sh:
#!/bin/bash
key="index.index";
arr[$key]="val"
echo ${arr[${key}]}
/bin/bash -x test.sh
/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!
为什么会出现此错误,任何建议将不胜感激!
回答by Keith Thompson
This:
这个:
key="index";
arr[$key]="val"
echo ${arr[${key}]}
only appearsto work. Since arr
is an ordinary array, not an associative array, it can only be indexed by non-negative integer values.
似乎只工作。由于arr
是普通数组,而不是关联数组,因此只能由非负整数值索引。
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.
所有的echo
语句打印val
。由于索引被视为算术表达式,因此它可以引用$index
带有或不带有$
前缀的变量(在本例中为)——即使它是一个带引号的字符串。
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]}
.
在您的代码中,您从未将值分配给$index
,${arr[${key}]}
扩展为${arr[index]}
,这等效于${arr[$index]}
,默认情况下将其视为等效于${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.)
(如果有set -o nounset
,则对未设置变量的引用将被视为错误,并且您的代码将产生错误消息。)
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.
无效,因为index.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
.
如果你想arr
允许任意字符串作为索引,它需要是一个关联数组。您可以简单地通过为其赋值(或使用declare -a
)来创建非关联数组,但只能使用 来创建关联数组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.
关联数组已添加到版本 4 中的 bash。如果您使用的是较早版本的 bash,declare -A
则不支持。您需要升级到更新的 bash,编写一些笨拙的替代方法,或者使用支持关联数组的语言,如 Awk、Python 或 Perl。
Adding declare -A arr
(as user000001's answersuggests) 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).
添加declare -A arr
(如user000001 的回答所建议的)应该可以解决问题(如果您有 bash 4),但了解您的原始代码实际在做什么(或者不做什么)是有益的。
(BTW, thanks for asking this; I learned a lot as I was composing this answer.)
(顺便说一句,感谢您提出这个问题;我在撰写此答案时学到了很多东西。)
回答by user000001
Declare the array variable as an associative array with declare -A arr
.
使用 将数组变量声明为关联数组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
回答by anubhava
This behavior varies by BASH version. Older BASH versions only allowed non negative integers as the keys in arrays.
此行为因 BASH 版本而异。较旧的 BASH 版本只允许非负整数作为数组中的键。
Please note that dot/period
is not allowed in a variable name in BASH.
请注意,dot/period
不允许在 BASH 中的变量名中使用。
See this Q&A for more details about allowed characters in BASH: Allowed characters in linux environment variable names
有关 BASH 中允许的字符的更多详细信息,请参阅此问答:Linux 环境变量名称中的允许字符
EDIT:
编辑:
(Many thanks to @chepner for this addendum)
(非常感谢@chepner 提供此附录)
Regular arrays (not associative array) are indexed by integer only. Any expression used as an index between square brackets is treated as an arithmetic expression. $key expands to index, which is then treated as an (unset) variable which expands to 0. If you assigned a value of, say, 3 to index, then ${array[$key]} -> ${array[index]} -> ${array[3]}
. It's a type of implicit indirect parameter expansion
常规数组(不是关联数组)仅由整数索引。任何用作方括号之间索引的表达式都被视为算术表达式。$key 扩展为 index,然后将其视为扩展为 0 的(未设置)变量。如果您将值 3 分配给 index,则${array[$key]} -> ${array[index]} -> ${array[3]}
. 这是一种隐式间接参数扩展