Bash将关联数组键解释为八进制数

Bash将关联数组键解释为八进制数,bash,associative-array,Bash,Associative Array,我如何防止失败: a[5c8]=1 -bash: 5c8: value too great for base (error token is "5c8") bash似乎将5c8解释为一个八进制数。显然,我可以在密钥中添加前缀,并在以后使用数组时删除该前缀,但我希望有一个更优雅的解决方案 Bash 4.3.48.除非您将数组声明为关联数组,否则所有数组键都将被解释为数字(或要计算以获得数字的变量名称),如声明-a: #!/usr/bin/env bash case $BASH_VERSION i

我如何防止失败:

a[5c8]=1
-bash: 5c8: value too great for base (error token is "5c8")
bash似乎将5c8解释为一个八进制数。显然,我可以在密钥中添加前缀,并在以后使用数组时删除该前缀,但我希望有一个更优雅的解决方案

Bash 4.3.48.

除非您将数组声明为关联数组,否则所有数组键都将被解释为数字(或要计算以获得数字的变量名称),如
声明-a

#!/usr/bin/env bash
case $BASH_VERSION in ''|[1-3].*) echo "Bash 4.0+ required" >&2; exit 1;; esac

declare -A a
a[5c8]=1

首先,您有一个索引数组,因此索引是在算术上下文中计算的

$ declare -A a
$ a[5c8]=1
$ declare -p a
declare -A a=([5c8]="1" )
其次,任何以数字开头的字符串都将被视为数字,而不是带有数值的标识符

$ foo=3
$ a[foo]=5
$ declare -p a
declare -a a=([3]="5")
那么5c8是多少
bash
提供了一组丰富的数字文本:

前导为0的常数被解释为八进制数。领头羊 0x或0x表示十六进制。否则,数字的形式为 [base#]n,其中可选的基数是介于2和64之间的十进制数 表示算术基数,n是该基数中的数字。如果 省略基数#,然后使用基数10。指定n时,数字 大于9的字符由小写字母表示,即大写字母 字母,@,和u,按顺序排列。如果基数小于或等于36, 小写和大写字母可以互换使用,以表示10到35之间的数字

它不是以10为基数的有效常量(默认值)。它对基数为13或更高的值有效,但
bash
不会尝试猜测您指的是哪一个


尽管如此,您可能意味着要将其视为文字字符串,在这种情况下,您需要将数组声明为关联数组,这样索引就不会在算术上下文中求值

$ declare -A a
$ a[5c8]=1
$ declare -p a
declare -A a=([5c8]="1" )

添加前缀并不明显,也不起作用。它只是作为一个不太可能存在的变量进行计算,因此相当于
a[0]
数字“c”对于基数10来说太大了。我很好奇OP从哪里得到八进制的概念。(如果键以0开头,可能是这样,但这里不是这样)。5c8在我看来像个十六进制数,但bash并不那么聪明。您尝试过添加0x前缀吗?
bash
不太聪明,因为它也是一个有效的base-13、base-14、…、和base-64数字。