5

在 bash 中编写if块时,shellcheck告诉我&&and||比使用-aand更受欢迎-o

为什么?它更快,还是只是为了使脚本看起来更干净的风格偏好?

我得到的具体信息是:

^-- SC2166: Prefer [ p ] || [ q ] as [ p -o q ] is not well defined.
4

1 回答 1

10

来自POSIX 规范test

  • 4个论点:

    结果未指定。

    [OB XSI] [选项开始] 在符合 XSI 的系统上,应使用前面描述的优先级和关联性规则来评估初级和运算符的组合。此外,字符串比较二元基元 '=' 和 "!=" 应具有比任何一元基元更高的优先级。[选项结束]

因此: 使用test三个以上的参数——如果你使用-aor -o,你依赖它——没有未扩展的 POSIX 明确指定的行为。


现在,为什么会这样?因为在某些情况下,解析器可能会根据变量值做错事。

你还记得有人建议做这样的事情吗?

if [ "x$foo" = "x$bar" ]; then ...

......这是愚蠢和古老的,对吧?其实,foo=(考虑and的情况bar=),并且有人运行这样的命令:

if [ "$foo" -a "$bar" ]

这扩展为以下内容:

if [ ( -a ) ]

...我们如何解析它?好吧,它可能是一个分组运算符(是的,test历史上被指定支持它们),检查是否-a为非空;或者它可以检查两者是否()本身都是非空字符串;这是模棱两可的。这种歧义是为什么-a并且-o不再是首选语法。


那么,替代品是什么样子的呢?代替:

[ "$foo" -gt "$bar" -a "$foo" -lt "$qux" ]

...你会这样写:

[ "$foo" -gt "$bar" ] && [ "$foo" -lt "$qux" ]

...关闭两个测试表达式并使用 shell 语法组合它们的输出。由于[/test是内置的 shell,它不需要作为外部命令执行,因此它没有 70 年代运行test意味着调用/usr/bin/test.

于 2016-01-12T23:44:34.643 回答