数组索引中的算术扩展 - 是否需要美元符号?
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。
我希望只有后者可以工作,因为我认为只有那个 returns 是算术表达式的结果。但是那里: Bash - arithmetic in array index 我读到只有第一个可能适用于旧版本的 bash (?)。那么究竟哪一个是正确的呢?为什么第一个有效?我还没有找到具体的答案。
美元符号在某些情况下是必需的,但在其他情况下则不需要:
$ 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 手册页后,compound commands 中不需要美元符号:
Compound commands are the shell programming constructs. Each construct begins with a reserved word or control operator and is terminated by a corresponding reserved word or operator. Any redirections (see Redirections) associated with a compound command apply to all commands within that compound command unless explicitly overridden.
In most cases a list of commands in a compound command’s description may be separated from the rest of the command by one or more newlines, and may be followed by a newline in place of a semicolon.
Bash provides looping constructs, conditional commands, and mechanisms to group commands and execute them as a unit.
for (( expr1 ; expr2 ; expr3 ))
是一个复合命令,因此不需要美元符号来启用算术计算.
而 echo $((expr))
不是 复合命令 因为它不是以保留的 bash 关键字开头,所以它需要美元符号才能启用 算术求值.
在数组中,bash 将 []
之间的表达式视为算术。于是
i=2 ; f[i++]=10
完美。写作 f[((i++))]
也是正确的,但在这种情况下,(())
不被视为算术扩展运算符,而是被视为嵌套的括号。
注意((expr))
计算expr
,如果为真则成功,而$((expr))
作为其值展开。所以f[$((i++))]
也是对的
最后,f[$i++]
不是您想要的,因为 $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 中的数组索引中使用算术扩展时,像这样:
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。
我希望只有后者可以工作,因为我认为只有那个 returns 是算术表达式的结果。但是那里: Bash - arithmetic in array index 我读到只有第一个可能适用于旧版本的 bash (?)。那么究竟哪一个是正确的呢?为什么第一个有效?我还没有找到具体的答案。
美元符号在某些情况下是必需的,但在其他情况下则不需要:
$ 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 手册页后,compound commands 中不需要美元符号:
Compound commands are the shell programming constructs. Each construct begins with a reserved word or control operator and is terminated by a corresponding reserved word or operator. Any redirections (see Redirections) associated with a compound command apply to all commands within that compound command unless explicitly overridden.
In most cases a list of commands in a compound command’s description may be separated from the rest of the command by one or more newlines, and may be followed by a newline in place of a semicolon.
Bash provides looping constructs, conditional commands, and mechanisms to group commands and execute them as a unit.
for (( expr1 ; expr2 ; expr3 ))
是一个复合命令,因此不需要美元符号来启用算术计算.
而 echo $((expr))
不是 复合命令 因为它不是以保留的 bash 关键字开头,所以它需要美元符号才能启用 算术求值.
在数组中,bash 将 []
之间的表达式视为算术。于是
i=2 ; f[i++]=10
完美。写作 f[((i++))]
也是正确的,但在这种情况下,(())
不被视为算术扩展运算符,而是被视为嵌套的括号。
注意((expr))
计算expr
,如果为真则成功,而$((expr))
作为其值展开。所以f[$((i++))]
也是对的
最后,f[$i++]
不是您想要的,因为 $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")'