Bash数组中的负下标

3
创建一个简单的bash堆栈脚本后,我遇到了与bash数组相关的错误。
来自Bash手册:
如果使用以下语法分配任何变量,则将自动创建索引数组:
name[subscript]=value name[subscript]=value。下标被视为必须评估为数字的算术表达式。如果下标评估为小于零的数字,则将其用作从大于数组最大索引的1开始的偏移量(因此,下标为-1是指数组的最后一个元素)。
在我的本地机器上一切都很完美,但不幸的是我的服务器环境略有不同。
负下标在Ubuntu 14.04 / GNU bash版本4.3.11(1)上运行得很好。但是,当我尝试在GNU bash版本4.2.46(1)的服务器上运行相同的脚本时,遇到了以下错误:
line 46: [-1]: bad array subscript 

我试图创建一个数组并直接从终端调用最后一个元素(不在脚本内部),它成功了:

user@local:~$ arr=( 1 2 3 4 5 )
user@local:~$ echo ${arr[-1]}
5

我有点困惑。这个问题有没有解决方案或变通方法?

1个回答

3

猜猜在Bash更改日志中有什么:

针对: 这个版本bash-4.3-beta和上一个版本bash-4.3-alpha之间的变化

x. 现在,shell允许使用负下标(a[-1]=2,echo ${a[-1]})来分配、引用和取消索引数组的元素,这些元素从数组的最后一个元素开始计数。

针对: 这个版本bash-4.2-alpha和上一个版本bash-4.1-release之间的变化

p. 以前错误的索引数组的负下标现在被视为距离最大分配索引+1的偏移量。

所以你的测试只是使用负偏移量进行读取(在 ~4.2及以上版本中可以),但你的错误源于尝试使用负偏移量进行分配或取消分配(在 ~4.3及以上版本中可以)。

也许你可以参考数组的长度,并进行一些计算:
(读取)${arr[${#arr[@]}-1]}
(分配)arr[${#arr[@]}-1]=last
(清除)unset arr[${#arr[@]}-1]


感谢您在此事上的澄清。我确实想要取消数组的最后一个元素。还有其他方法吗?有什么解决方案或变通方法吗? - Ludi
我在考虑创建类似于:array[arrayLength - 1] - Ludi
@Ludi 好的,我建议使用其他方法来分配和取消最后一个元素。 - dlamblin
@Ludi 在你的代码片段中仍然有[-1]下标。相反,我认为它应该像这样:function stateMachine.pop() { : ${1? '缺少属性名'} local attribute="${1}"; local arrayName=STATE_MACHINE_${attribute}; # if [[ ! $( stateMachine.exist "${arrayName}" ) == 0 ]]; then local arrayLength=${#"${arrayName}"[@]};unset "${arrayName}[$arrayLength-1]"; fi } - dlamblin
谢谢您的帮助,但它仍然无法正常工作。在使用您的解决方案后,我收到了以下错误消息:line 46: ${#{arrayName}[@]}: bad substitution我不知道为什么会这样,但我会继续尝试! - Ludi
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接