繁体   English   中英

Bash:数组索引中的算术扩展 - 是否需要美元符号?

[英]Bash: arithmetic expansion in array indices - is the dollar sign needed?

当我在 bash 中的数组索引中使用算术扩展时,如下所示:

declare -a FILES
declare -i INDEX=0

for FILE in ./*
do
    FILES[((INDEX++))]="$FILE"
done

我需要在 ((...)) 前面加一个美元符号吗?
所以它必须是:

FILES[((INDEX++))]="$FILE"

或者更确切地说:

FILES[$((INDEX++))]="$FILE"

?
在我的本地 bash 副本中,这两个变体似乎都可以工作 - 它的版本是 4.3.30。
我希望只有后者能工作,因为我认为只有一个返回算术表达式的结果。 但是有: Bash - 数组索引中的算术我读过只有第一个可能适用于旧版本的 bash (?)。 那么究竟哪一个是正确的呢? 为什么第一个有效? 我还没有找到具体的答案。

在数组中,bash 将[]之间的表达式视为算术。 因此

i=2 ; f[i++]=10

是完美的。 编写f[((i++))]也是正确的,但在这种情况下, (())不被视为算术扩展运算符,而是被视为嵌套括号。

请注意, ((expr))计算expr ,如果它为真则成功,而$((expr))被扩展为它的值。 所以f[$((i++))]也是正确的。

最后, f[$i++]不是你想要的,因为$i首先被扩展。 例如, i=j ; f[$i++] i=j ; f[$i++]将被扩展为f[j++]

备注:一个奇怪的特性是 bash 在没有$符号的情况下在算术模式下扩展了它的所有功能:

$ unset i j k f
$ i=j ; j=k ; k=5 ; f[i++]=10
$ declare -p i j k f
declare -- i="6"
declare -- j="k"
declare -- k="5"
declare -a f='([5]="10")'

在某些情况下需要美元符号,但在其他情况下不需要:

$ bash --version
GNU bash, version 4.3.42(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

$ echo ((1+2))
bash: syntax error near unexpected token `('

$ echo $((1+2))
3

$ for ((x=0; x<3;++x)); do echo $x; done
0
1
2

$ for $((x=0; x<3;++x)); do echo $x; done
bash: `$((x=0; x<3;++x))': not a valid identifier

阅读 bash 手册页后, 复合命令中不需要美元符号:

复合命令是 shell 编程结构。 每个构造都以保留字或控制运算符开始,并以相应的保留字或运算符终止。 除非明确覆盖,否则与复合命令关联的任何重定向(请参阅重定向)都适用于该复合命令中的所有命令。

在大多数情况下,复合命令描述中的命令列表可能与命令的其余部分用一个或多个换行符分隔,并且后面可能跟一个换行符代替分号。

Bash 提供循环结构、条件命令和将命令分组并作为一个单元执行的机制。

for (( expr1 ; expr2 ; expr3 ))是一个复合命令,因此启用算术计算不需要美元符号。

echo $((expr))不是复合命令,因为它不以保留的 bash 关键字开头,因此它需要一个美元符号才能启用算术评估

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM