测试运算符 -a 和 -o 是否短路?
Do test operators -a and -o short circuit?
test
运算符-a
和-o
是否短路?
我试过 if [ 0 -eq 1 -a "" -eq 0 ]; then ...
,它抱怨第二个条件的语法。但我不知道那是不是因为
-a
不短路
- 或
test
希望在开始之前正确格式化所有内容,但它仍然短路。
结果导致我创建了一个嵌套的 if
,而我真正想要的是第一个条件将防止在尚未设置特定变量的情况下执行第二个条件...
编辑: 至于我为什么要使用过时的运算符,代码必须在我的环境中随处可用,我刚找到一台机器
while [ -L "$file" ] && [ "$n" -lt 10 ] && [ "$m" -eq 0 ]; do
是一个无限循环,更改为过时的 -a
会产生良好的行为:
while [ -L "$file" -a "$n" -lt 10 -a "$m" -eq 0 ]; do
我该怎么办?第一个表达式适用于许多机器,但不适用于这台机器,它似乎需要第二个表达式...
根据 the POSIX specification for test:
>4 arguments:
The results are unspecified.
因此,除了 XSI 扩展,POSIX 没有说明其行为方式。
此外,即使在 具有 XSI 扩展的系统上:
expression1 -a expression2
: True if both expression1 and expression2 are true; otherwise, false. The -a binary primary is left associative. It has a higher precedence than -o. [Option End]
expression1 -o expression2
: True if either expression1 or expression2 is true; otherwise, false. The -o binary primary is left associative. [Option End]
没有关于短路的规范。
如果您想要短路行为——或者 POSIX 定义的行为——使用 &&
和 ||
连接多个单独的测试调用。
再次引用文档后面的内容:
APPLICATION USAGE
The XSI extensions specifying the -a and -o binary primaries and the '(' and ')' operators have been marked obsolescent. (Many expressions using them are ambiguously defined by the grammar depending on the specific expressions being evaluated.) Scripts using these expressions should be converted to the forms given below. Even though many implementations will continue to support these obsolescent forms, scripts should be extremely careful when dealing with user-supplied input that could be confused with these and other primaries and operators. Unless the application developer knows all the cases that produce input to the script, invocations like:
test "" -a ""
should be written as:
test "" && test ""
好吧,您已经知道这种行为了,所以这个问题实际上是关于如何解释这些结果的。但是说实话,您会观察到不同行为的真实场景并不多。
我创建了一个小测试用例来检查发生了什么(至少,在 my 系统上,因为另一个答案表明它不是标准化的):
strace bash -c "if [ 0 -eq 1 -a -e "/nosuchfile" ]; then echo X; fi"
如果您检查输出,您会看到 bash 查找文件,所以答案是:
运营商没有短路
test
运算符-a
和-o
是否短路?
我试过 if [ 0 -eq 1 -a "" -eq 0 ]; then ...
,它抱怨第二个条件的语法。但我不知道那是不是因为
-a
不短路- 或
test
希望在开始之前正确格式化所有内容,但它仍然短路。
结果导致我创建了一个嵌套的 if
,而我真正想要的是第一个条件将防止在尚未设置特定变量的情况下执行第二个条件...
编辑: 至于我为什么要使用过时的运算符,代码必须在我的环境中随处可用,我刚找到一台机器
while [ -L "$file" ] && [ "$n" -lt 10 ] && [ "$m" -eq 0 ]; do
是一个无限循环,更改为过时的 -a
会产生良好的行为:
while [ -L "$file" -a "$n" -lt 10 -a "$m" -eq 0 ]; do
我该怎么办?第一个表达式适用于许多机器,但不适用于这台机器,它似乎需要第二个表达式...
根据 the POSIX specification for test:
>4 arguments: The results are unspecified.
因此,除了 XSI 扩展,POSIX 没有说明其行为方式。
此外,即使在 具有 XSI 扩展的系统上:
expression1 -a expression2
: True if both expression1 and expression2 are true; otherwise, false. The -a binary primary is left associative. It has a higher precedence than -o. [Option End]
expression1 -o expression2
: True if either expression1 or expression2 is true; otherwise, false. The -o binary primary is left associative. [Option End]
没有关于短路的规范。
如果您想要短路行为——或者 POSIX 定义的行为——使用 &&
和 ||
连接多个单独的测试调用。
再次引用文档后面的内容:
APPLICATION USAGE
The XSI extensions specifying the -a and -o binary primaries and the '(' and ')' operators have been marked obsolescent. (Many expressions using them are ambiguously defined by the grammar depending on the specific expressions being evaluated.) Scripts using these expressions should be converted to the forms given below. Even though many implementations will continue to support these obsolescent forms, scripts should be extremely careful when dealing with user-supplied input that could be confused with these and other primaries and operators. Unless the application developer knows all the cases that produce input to the script, invocations like:
test "" -a ""
should be written as:
test "" && test ""
好吧,您已经知道这种行为了,所以这个问题实际上是关于如何解释这些结果的。但是说实话,您会观察到不同行为的真实场景并不多。
我创建了一个小测试用例来检查发生了什么(至少,在 my 系统上,因为另一个答案表明它不是标准化的):
strace bash -c "if [ 0 -eq 1 -a -e "/nosuchfile" ]; then echo X; fi"
如果您检查输出,您会看到 bash 查找文件,所以答案是:
运营商没有短路