【问题标题】:"... && ... || ..." (short-circuiting boolean) not identical to "if ...; then ...; else ...; fi" [duplicate]“... && ... || ...”(短路布尔值)与“if ...; then ...; else ...; fi”不同 [重复]
【发布时间】:2019-06-20 12:50:28
【问题描述】:

我刚刚在编写 if/then/else 块的替代形式时得到了意想不到的结果。

> #this is the behaviour I expect:  
> if [[ 1 -eq 1 ]]; then echo "good"; false; else   echo "bad"; fi
good

> #assuming no error in the first block these brackets behave okay as well:
> [[ 1 -eq 1 ]] && { echo "good"; } || { echo "bad"; }
good

> #this however allows the process to jump into the first AND second block
> [[ 1 -eq 1 ]] && { echo "good"; false; } || { echo "bad"; }
good
bad

为什么花括号方法将进程传递到第二个块。我知道有些语句在块结束之前必须有一个;,但是如果 bash 块在错误条件下作为最后一条语句表现不佳,这些块似乎“不安全”使用。

【问题讨论】:

  • foo && bar || baz 是完全安全的,只要您不尝试将它们用作它们不是的东西。他们不是if; then; else
  • 这就是为什么shellcheck.net 标记foo && bar || baz 并带有警告SC2015,以劝阻那些在不知道它实际作用的情况下使用它的人。
  • (这和代码块有什么关系?对于any命令也是一样的;不管是单个命令回显某些东西然后返回false,还是单独的echofalse 一个块中的命令)。

标签: bash conditional-statements codeblocks


【解决方案1】:

因为|| 的功能是在其左侧返回非零时执行其右侧,false 会这样做。

&&/|| 不是 if/else,也不是 ?: 三元运算符 - 它是一对链接的单独操作。

【讨论】:

    【解决方案2】:

    shell 中的&&|| 运算符处理每个语句的返回值(退出代码)。在{ } 内的复合语句中,最后一条命令的退出状态是重要的。

    [[ 1 -eq 1 ]] && { echo "good"; } || { echo "bad"; }
    

    相当于:

    true && true || true
    

    所以true && true 的计算结果为true,而shell“短路”(即不计算){ echo "bad"; },因为true || anything 为真。

    [[ 1 -eq 1 ]] && { echo "good"; false; } || { echo "bad"; }
    

    相当于:

    true && false || true
    

    在这种情况下,true && false 的计算结果为 false,shell 必须计算完整的表达式。

    if/else 代码采用第一个分支,因为[[ 1 -eq 1 ]] 的退出代码是0(与shell 中的true 相同)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-10
      • 1970-01-01
      • 2013-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多