Eta*_*ner 5 bash shell ksh posix arithmetic-expressions
POSIX 规范在算术扩展方面指出
[i] 如果 shell 变量 x 包含一个形成有效整数常量的值,可选地包括前导加号或减号,那么算术扩展“$((x))”和“$(($x))”应返回相同的值。
这是一个合理的快捷方式,可以很好地清理复杂的表达式。
bash(3.2.25(1)-release
来自 CentOS 5 的版本和4.3.33(1)-release
来自 debian stable 的版本)以及 ksh(Version AJM 93t+ 2010-06-21
来自 CentOS 5 的版本)似乎都比这更进一步。
它们似乎都递归地扩展在算术扩展中遇到的变量(以及[[
使用数字运算符产生的数字上下文)。
具体来说:
$ set -x
$ bar=5
+ bar=5
$ foo=bar
+ foo=bar
$ [ foo -gt 4 ]; echo $?
+ '[' foo -gt 4 ']'
-bash: [: foo: integer expression expected
+ echo 2
2
$ [[ foo -gt 4 ]]; echo $?
+ [[ foo -gt 4 ]]
+ echo 0
0
$ [[ foo -eq 0 ]]; echo $?
+ [[ foo -eq 0 ]]
+ echo 1
1
$ [[ foo -eq 5 ]]; echo $?
+ [[ foo -eq 5 ]]
+ echo 0
0
$ (( foo == bar )); echo $?
+ (( foo == bar ))
+ echo 0
0
$ (( foo == 1 )); echo $?
+ (( foo == 1 ))
+ echo 1
1
Run Code Online (Sandbox Code Playgroud)
这种行为从何而来,为什么它会是可取的?
当与数字运算符一起使用时[[
,它会[
显式降低使用的安全性,因为无效值和印刷错误会从脚本错误变为静默有效(但可能是错误的)测试。
编辑:作为一个附带问题,如果有人碰巧知道此“功能”何时添加到 bash/etc. 我也有兴趣了解这一点。
情况比你想象的还要糟糕。变量的值被递归地视为算术表达式:
\n\n$ foo=\'bar+bar\'\n$ echo $((foo))\n10\n
Run Code Online (Sandbox Code Playgroud)\n\nbash 手册中关于Shell 算术的部分说:
\n\n\n\n\n当引用变量时,或者为使用 \xe2\x80\x98declare -i\xe2\x80\x99 赋予整数属性的变量赋值时,变量的值将被计算为算术表达式。
\n
后一部分意味着你可以这样做:
\n\n$ declare -i int\n$ int=bar+bar\n$ echo $int\n10\n
Run Code Online (Sandbox Code Playgroud)\n\n请注意,这一切都不违反您上面引用的规范。它只说明如果变量的值是整数常量应该做什么。它没有说明如果该值是其他值应该做什么,这为实现添加这样的扩展留下了空间。Bash Hackers Wiki对此进行了解释:
\n\n\n\n\n如果变量不包含看起来像有效表达式(数字或运算)的值,则该表达式将被重新用于引用,例如命名参数
\n
如果最终的扩展不是有效的表达式,您将收到错误:
\n\n$ foo=\'a b\'\n$ bar=foo\necho $((bar))\nbash: a b: syntax error in expression (error token is "b")\n
Run Code Online (Sandbox Code Playgroud)\n\n因此,如果您的变量包含随机内容,则可能会导致错误。但是,如果它只包含一个单词(这是有效的变量语法),那么它将像0
未设置变量一样进行评估。
归档时间: |
|
查看次数: |
1427 次 |
最近记录: |