为什么要避免在 bash 脚本中使用“&&”?

为什么要避免在 bash 脚本中使用“&&”?

我正在编写一个 bash 脚本,其中包含一个简单的 if 部分,其中有两个条件:

  if [[ -n $VAR_A ]] && [[ -n $VAR_B ]]; then
    echo >&2 "error: cannot use MODE B in MODE A" && exit 1
  fi

一位高级工程师审查了我的代码并评论道:

当您可以简单地执行后续行中的两个命令时,请避免使用 && 。

他没有进一步解释。但出于好奇,我想知道这是否属实,以及避免使用&&.

答案1

审稿意见大概是指&&操作符的第二种用法。你不想不退出我想,如果echo失败,那么将命令写在单独的行上更有意义:

if [[ -n $VAR_A ]] && [[ -n $VAR_B ]]; then
    echo >&2 "error: cannot use MODE B in MODE A"
    exit 1
fi

顺便说一句,在 bash 中你可以包含&&以下[[ ... ]]条件:

if [[ -n $VAR_A && -n $VAR_B ]]; then

答案2

这不是一般性的反对评论&&。我怀疑与您交谈的工程师正在考虑(可能性很小,但理论上仍然可能)本身echo失败的情况。如果你有这个:

if error; then
    echo foo && exit
fi

然后,如果由于某种原因echo命令失败,则该命令exit将不会运行,因此您实际上不会捕获错误。如果将它们分开,exit即使echo失败也会运行:

if error; then
    echo foo
    exit 
fi

所以工程师确实是对的,将这两个具体的语句分开比较安全。但是,不要将其解释为反对使用 的一般指令&&。您应该简单地确保&&仅在您确实希望使一个命令的执行取决于另一个命令的成功执行的情况下使用。

例如,这完全没问题:

command && echo 'command worked!' 

答案3

人们已经为失败提出了很好的理由echo。除了关于正确性的这一点之外,您还可以说明可读性。你写了

echo >&2 "error: cannot use MODE B in MODE A" && exit 1

当我在脑子里把它翻译成英语时,我得到的是这样的信息:

将以下内容打印到标准错误:“错误:无法在模式 A 中使用模式 B”
如果打印操作成功完成,则以代码 1 退出

读到这里的人可能会问,“为什么你要费心指定如果打印操作成功完成在这种情况下,这两行比 更简单,&&因为代码中的逻辑较少。推荐的两行替代方案的英文版本是:

将以下内容打印到标准错误:“错误:无法在模式 A 中使用模式 B”,
然后以代码 1 退出

这不那么复杂,所以阅读它需要更少的脑力。我们不会想知道它的&&用途。

答案4

无需在一行上编写两个命令。如果你的 if 语句中有 100 个命令,你不会 && 将它们放在一起,因为读起来很糟糕。虽然有关回声失败可能性的其他响应在技术上是正确的,但我怀疑高级开发人员的意图是为了可读性。

相关内容