为什么&&和||优先选择-a和-o

时间:2016-01-12 23:25:04

标签: bash shell shellcheck

在bash中编写if个阻止时,shellcheck告诉我&&||首选使用-a-o。< / p>

为什么呢?它更快,或者只是简单的风格偏好使脚本看起来更干净?

我得到的具体信息是:

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

1 个答案:

答案 0 :(得分:8)

来自the POSIX specification for test

  
      
  • 4个论点:

         

    结果未明确。

         

    [OB XSI] [选项开始]在符合XSI的系统上,应使用前面描述的优先级和关联性规则评估原色和运算符的组合。此外,字符串比较二进制初级'='和“!=”应优先于任何一元初级。 [选项结束]

  •   

因此:test使用超过三个参数 - 如果您使用-a-o,则依赖于此 - 没有明确指定的行为由未扩展的POSIX。

现在,为什么会这样呢?因为有些情况下解析器可以根据变量值执行错误的操作。

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

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

......这是愚蠢而古老的,对吗?实际上,没有!考虑foo=(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