我正在编写一个 bash 脚本,其中包含一个简单的 if 部分,其中有两个条件:
if [[ -n $VAR_A ]] && [[ -n $VAR_B ]]; then
echo >&2 "error: cannot use MODE B in MODE A" && exit 1
fi
Run Code Online (Sandbox Code Playgroud)
一位高级工程师审查了我的代码并评论道:
当您可以简单地执行后续行中的两个命令时,请避免使用 && 。
他没有进一步解释。但出于好奇,我想知道这是否属实,以及避免使用&&
.
cho*_*oba 94
审稿意见大概是指&&
操作符的第二种用法。我想,如果失败,您不想不退出echo
,因此将命令写在单独的行上更有意义:
if [[ -n $VAR_A ]] && [[ -n $VAR_B ]]; then
echo >&2 "error: cannot use MODE B in MODE A"
exit 1
fi
Run Code Online (Sandbox Code Playgroud)
顺便说一句,在 bash 中你可以包含&&
以下[[ ... ]]
条件:
if [[ -n $VAR_A && -n $VAR_B ]]; then
Run Code Online (Sandbox Code Playgroud)
ter*_*don 69
这不是一般性的反对评论&&
。我怀疑与您交谈的工程师正在考虑(可能性很小,但理论上仍然可能)本身echo
失败的情况。如果你有这个:
if error; then
echo foo && exit
fi
Run Code Online (Sandbox Code Playgroud)
然后,如果由于某种原因echo
命令失败,则该命令exit
将不会运行,因此您实际上不会捕获错误。如果将它们分开,exit
即使echo
失败也会运行:
if error; then
echo foo
exit
fi
Run Code Online (Sandbox Code Playgroud)
所以工程师确实是对的,将这两个具体的语句分开比较安全。但是,不要将其解释为反对使用 的一般指令&&
。您应该简单地确保&&
仅在您确实希望使一个命令的执行取决于另一个命令的成功执行的情况下使用。
例如,这完全没问题:
command && echo 'command worked!'
Run Code Online (Sandbox Code Playgroud)
小智 23
人们已经为失败提出了很好的理由echo
。除了关于正确性的这一点之外,您还可以说明可读性。你写了
echo >&2 "error: cannot use MODE B in MODE A" && exit 1
Run Code Online (Sandbox Code Playgroud)
当我在脑子里把它翻译成英语时,我得到的是这样的信息:
将以下内容打印到标准错误:“错误:无法在模式 A 中使用模式 B”
如果打印操作成功完成,则以代码 1 退出
读到这里的人可能会问,“为什么你要费心指定打印操作是否成功完成”?在本例中,这两行比 更简单,&&
因为代码中的逻辑较少。推荐的两行替代方案的英文版本是:
将以下内容打印到标准错误:“错误:无法在模式 A 中使用模式 B”
,然后以代码 1 退出
这不那么复杂,所以阅读它需要更少的脑力。我们不会想知道它&&
的用途。
Aus*_*arn 21
简而言之,您不应假设在退出路径中执行的代码本身不会导致错误。这并非特定于 shell 脚本,而是一般意义上的良好编程建议。
\n通过使用echo \xe2\x80\x98foo\xe2\x80\x99 && exit
,您只会在echo \'foo\'
成功时退出。失败的可能性确实非常低,但你不应该指望这一点,特别是当正确执行任务的成本如此之低时。当您有一个更复杂的退出路径可能会调用代码中的其他函数并且 \xe2\x80\x99 并不明显您的退出路径只会调用 \xe2\x80\x98mostly safe\xe2\x80\ 时,这一点变得更加重要x99之类的东西echo
,但它\xe2\x80\x99s通常是在所有情况下使用\xe2\x80\x98正确\xe2\x80\x99代码的良好形式,这样你就养成了正确执行它的习惯(这样你的同事就知道什么期待)。
如果出于某种原因,您需要将其作为一行(但我认为永远不应该出现这种情况),则正确的语法是echo \'foo\' ; exit
,这会导致解析器将这两个命令视为位于不同的行上。
顺便说一句,在你的条件中,你几乎总是应该选择:
\nif [[ -n $VAR_A && -n $VAR_B ]]; then\n
Run Code Online (Sandbox Code Playgroud)\n这是 bash 特定的,但比您当前拥有的更有效,或者:
\nif [ -n "$VAR_A" ] && [ -n "$VAR_B" ]; then\n
Run Code Online (Sandbox Code Playgroud)\n它将在任何符合 POSIX 的 shell 中以语义等效的方式工作。
\n