IsaIkari Asked: 2022-01-04 07:38:55 +0800 CST2022-01-04 07:38:55 +0800 CST 2022-01-04 07:38:55 +0800 CST 为什么要避免在 bash 脚本中使用“&&”? 772 我正在编写一个 bash 脚本,其中包含一个带有两个条件的简单 if 部分: if [[ -n $VAR_A ]] && [[ -n $VAR_B ]]; then echo >&2 "error: cannot use MODE B in MODE A" && exit 1 fi 一位高级工程师查看了我的代码并评论说: 当您可以简单地在后续行中执行这两个命令时,请避免使用 &&。 他没有进一步解释。但出于好奇,我想知道这是否属实,以及避免使用&&. bash shell 5 个回答 Voted Best Answer choroba 2022-01-04T07:45:53+08:002022-01-04T07:45:53+08:00 审稿意见大概是指&&算子的第二种用法。如果失败,你不想不退出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 terdon 2022-01-04T07:53:52+08:002022-01-04T07:53:52+08:00 这不是反对的一般性评论&&。我怀疑与您交谈的工程师正在考虑(非常不可能,但理论上仍然可能)echo自身失败的情况。如果你有这个: if error; then echo foo && exit fi 然后,如果由于某种原因echo命令失败,exit则不会运行,因此您实际上不会捕获错误。如果将它们分开,exit即使echo失败也会运行: if error; then echo foo exit fi 所以工程师确实是对的,将这两个特定的语句分开更安全。但是,不要将其解释为反对使用&&. 您只需确保&&仅在您确实希望执行一个命令取决于另一个命令的成功执行的情况下使用。 例如,这很好: command && echo 'command worked!' alexanderbird 2022-01-05T23:12:36+08:002022-01-05T23:12:36+08:00 人们为echo失败提供了很好的理由。除了关于正确性的这一点之外,您还可以说明可读性。你写了 echo >&2 "error: cannot use MODE B in MODE A" && exit 1 当我在脑海中将其翻译成英语时,我得到如下信息: 如果打印操作成功完成,则将以下内容打印到标准错误:“错误:无法在模式 A 中使用模式 B” ,然后以代码 1 退出 读到这里的人可能会问,“你为什么要指定打印操作是否成功完成”?在这种情况下,这两行比 更简单,&&因为代码中的逻辑更少。推荐的两行替代方案的英文版本是: 将以下内容打印到标准错误:“错误:无法在模式 A 中使用模式 B”, 然后使用代码 1 退出 这不那么复杂,因此阅读它需要更少的脑力。我们不会想知道&&它的用途。 Austin Hemmelgarn 2022-01-05T04:47:17+08:002022-01-05T04:47:17+08:00 简而言之,您不应该假设在退出路径中执行的代码本身不会导致错误。这不是特定于 shell 脚本,而只是一般的良好编程建议。 通过使用echo ‘foo’ && exit,您将仅在echo 'foo'成功时退出。这种失败的可能性确实非常低,但你不应该指望它,尤其是当做对的成本如此之低时。当您有一个更复杂的退出路径可能会调用代码中的其他函数并且退出路径只会调用“最安全”的东西时,这一点变得更加echo重要在所有情况下,这样你才能养成正确做事的习惯(这样你的同事就会知道会发生什么)。 如果出于某种原因,您需要将其作为一行(我认为这绝不应该是这种情况),正确的语法是echo 'foo' ; exit,这会导致解析器将这两个命令视为在不同的行上。 顺便说一句,在您的条件中,您几乎应该总是更喜欢: if [[ -n $VAR_A && -n $VAR_B ]]; then 这是特定于 bash 的,但比您目前拥有的更有效,或者: if [ -n "$VAR_A" ] && [ -n "$VAR_B" ]; then 它将在任何符合 POSIX 的 shell 中以语义等效的方式工作。 Phil Barr 2022-01-12T15:06:35+08:002022-01-12T15:06:35+08:00 没有必要在一行上写两个命令。如果你的 if 语句中有 100 个命令,你就不会 && 将它们放在一起,因为读起来会很糟糕。虽然其他关于回声失败可能性的回应在技术上是正确的,但我怀疑高级开发人员的意图是关于可读性。
审稿意见大概是指
&&
算子的第二种用法。如果失败,你不想不退出echo
,我猜,所以在单独的行上编写命令更有意义:顺便说一句,在 bash 中,您可以
&&
在[[ ... ]]
条件中包含:这不是反对的一般性评论
&&
。我怀疑与您交谈的工程师正在考虑(非常不可能,但理论上仍然可能)echo
自身失败的情况。如果你有这个:然后,如果由于某种原因
echo
命令失败,exit
则不会运行,因此您实际上不会捕获错误。如果将它们分开,exit
即使echo
失败也会运行:所以工程师确实是对的,将这两个特定的语句分开更安全。但是,不要将其解释为反对使用
&&
. 您只需确保&&
仅在您确实希望执行一个命令取决于另一个命令的成功执行的情况下使用。例如,这很好:
人们为
echo
失败提供了很好的理由。除了关于正确性的这一点之外,您还可以说明可读性。你写了当我在脑海中将其翻译成英语时,我得到如下信息:
读到这里的人可能会问,“你为什么要指定打印操作是否成功完成”?在这种情况下,这两行比 更简单,
&&
因为代码中的逻辑更少。推荐的两行替代方案的英文版本是:这不那么复杂,因此阅读它需要更少的脑力。我们不会想知道
&&
它的用途。简而言之,您不应该假设在退出路径中执行的代码本身不会导致错误。这不是特定于 shell 脚本,而只是一般的良好编程建议。
通过使用
echo ‘foo’ && exit
,您将仅在echo 'foo'
成功时退出。这种失败的可能性确实非常低,但你不应该指望它,尤其是当做对的成本如此之低时。当您有一个更复杂的退出路径可能会调用代码中的其他函数并且退出路径只会调用“最安全”的东西时,这一点变得更加echo
重要在所有情况下,这样你才能养成正确做事的习惯(这样你的同事就会知道会发生什么)。如果出于某种原因,您需要将其作为一行(我认为这绝不应该是这种情况),正确的语法是
echo 'foo' ; exit
,这会导致解析器将这两个命令视为在不同的行上。顺便说一句,在您的条件中,您几乎应该总是更喜欢:
这是特定于 bash 的,但比您目前拥有的更有效,或者:
它将在任何符合 POSIX 的 shell 中以语义等效的方式工作。
没有必要在一行上写两个命令。如果你的 if 语句中有 100 个命令,你就不会 && 将它们放在一起,因为读起来会很糟糕。虽然其他关于回声失败可能性的回应在技术上是正确的,但我怀疑高级开发人员的意图是关于可读性。