【发布时间】:2015-05-25 03:08:04
【问题描述】:
据我所知,考虑到[[ 的一些额外功能,[[ 和 [ 的行为可能基本相同。但最近我注意到 bash 处理八进制扩展的方式存在差异:
$ b=010; echo $((b))
8
$ [[ $b -eq 8 ]]; echo $?
0
但是
$ [ $b -eq 8 ]; echo $?
1
$ test $b -eq 8; echo $?
1
$ [ $b -eq 10 ]; echo $?
0
为什么后一个表达式会放弃自动八进制转换?根据 Bash 中的 help test 和 Bash Reference Manual,-eq 之类的表达式是“算术”,进一步根据参考手册的下一部分,带有前导零的常量可以被视为八进制。
POSIX sh 不太清楚on the subject:尽管 POSIX 算术表达式仍将前导零整数扩展为八进制值,但它在 test 中将 -eq 表达式称为 algebraic ,而不是算术。
是否有任何文档或证据表明 bash 故意区分 [[ 和 [ 以进行八进制扩展,或者这只是一个偶然的功能?
【问题讨论】:
-
+1;但我注意到虽然
-eq被描述为“算术二元运算符”,但它的参数not 被描述为“算术表达式”。因此,例如,[ b -eq 10 ]不会扩展 shell 参数$b。因此,虽然该操作员将010视为 8 而不是 10 肯定更有意义,但我在手册中没有看到任何与您所看到的行为真正矛盾的内容。 -
[[ b -eq 8 ]]似乎等同于(( b == 8 ))(您可以省略$)。文档似乎没有这样说。 -
@choroba 好点,我什至没有意识到
[[ x -eq y ]]扩展 x 和 y 就像(( ))表达式一样。 -
自从你提出来,我试过
[[ 9-1 -eq b ]],退出状态是0。所以在[[ … -eq … ]]里面,bash 清楚地推断出一个算术上下文。去图吧。 -
这是一个众所周知的特性(或者应该是),而且还知道算术上下文(无论是
((...))还是[[ ... -eq ... ]])都会导致代码注入。例如,一个有趣的:a='a[$(ls >&2)]'; if [[ $a -eq 42 ]]; then echo yes; fi.