为什么 && 和 ||优于 -a 和 -o
Why are && and || preferred to -a and -o
在 bash 中写入 if
块时,shellcheck 告诉我 &&
和 ||
比使用 -a
和 -o
.
为什么?它更快,或者只是一种让脚本看起来更简洁的风格偏好?
我得到的具体信息是:
^-- SC2166: Prefer [ p ] || [ q ] as [ p -o q ] is not well defined.
来自 the POSIX specification for test
:
4 arguments:
The results are unspecified.
[OB XSI] [Option Start] On XSI-conformant systems, combinations of primaries and operators shall be evaluated using the precedence and associativity rules described previously. In addition, the string comparison binary primaries '=' and "!=" shall have a higher precedence than any unary primary. [Option End]
因此:使用带有三个以上参数的 test
—— 如果你使用 -a
或 -o
,你依赖于它 —— 没有行为由未扩展 POSIX.
明确指定
现在,为什么会这样?因为在某些情况下,解析器可能会根据变量值做错事。
你还记得有人建议你做这样的事情吗?
if [ "x$foo" = "x$bar" ]; then ...
...这很愚蠢很古老,对吧?实际上,没有!考虑 foo=(
和 bar=)
的情况,有人运行这样的命令:
if [ "$foo" -a "$bar" ]
扩展为以下内容:
if [ ( -a ) ]
...我们如何解析它?嗯,它 可以 是一个分组运算符(是的,test
在历史上被指定支持它们),检查 -a
是否是 non-null;或者它可以检查 (
和 )
本身是否都是 non-empty 字符串;这是模棱两可的。这种歧义是 -a
和 -o
不再是首选语法的原因。
那么,替代品是什么样子的?而不是:
[ "$foo" -gt "$bar" -a "$foo" -lt "$qux" ]
...你会这样写:
[ "$foo" -gt "$bar" ] && [ "$foo" -lt "$qux" ]
...关闭两个测试表达式并使用 shell 语法组合它们的输出。由于 [
/ test
是一个 shell 内建函数,它不需要作为外部命令执行,所以它没有像以前那样的性能开销70 年代 运行 test
意味着调用 /usr/bin/test
.
在 bash 中写入 if
块时,shellcheck 告诉我 &&
和 ||
比使用 -a
和 -o
.
为什么?它更快,或者只是一种让脚本看起来更简洁的风格偏好?
我得到的具体信息是:
^-- SC2166: Prefer [ p ] || [ q ] as [ p -o q ] is not well defined.
来自 the POSIX specification for test
:
4 arguments:
The results are unspecified.
[OB XSI] [Option Start] On XSI-conformant systems, combinations of primaries and operators shall be evaluated using the precedence and associativity rules described previously. In addition, the string comparison binary primaries '=' and "!=" shall have a higher precedence than any unary primary. [Option End]
因此:使用带有三个以上参数的 test
—— 如果你使用 -a
或 -o
,你依赖于它 —— 没有行为由未扩展 POSIX.
现在,为什么会这样?因为在某些情况下,解析器可能会根据变量值做错事。
你还记得有人建议你做这样的事情吗?
if [ "x$foo" = "x$bar" ]; then ...
...这很愚蠢很古老,对吧?实际上,没有!考虑 foo=(
和 bar=)
的情况,有人运行这样的命令:
if [ "$foo" -a "$bar" ]
扩展为以下内容:
if [ ( -a ) ]
...我们如何解析它?嗯,它 可以 是一个分组运算符(是的,test
在历史上被指定支持它们),检查 -a
是否是 non-null;或者它可以检查 (
和 )
本身是否都是 non-empty 字符串;这是模棱两可的。这种歧义是 -a
和 -o
不再是首选语法的原因。
那么,替代品是什么样子的?而不是:
[ "$foo" -gt "$bar" -a "$foo" -lt "$qux" ]
...你会这样写:
[ "$foo" -gt "$bar" ] && [ "$foo" -lt "$qux" ]
...关闭两个测试表达式并使用 shell 语法组合它们的输出。由于 [
/ test
是一个 shell 内建函数,它不需要作为外部命令执行,所以它没有像以前那样的性能开销70 年代 运行 test
意味着调用 /usr/bin/test
.