哪个更好:使用 ; 或 && 在一行中执行多个命令?

don*_*oey 553 command-line bash

在教程和操作指南中,我经常看到命令组合在一起。例如,

sudo apt-get update && sudo apt-get install pyrenamer
Run Code Online (Sandbox Code Playgroud)

似乎有四种可能的连接器:&&&||;。尽管& 连接器对我来说很清楚(它将进程发送到后台并使终端可用),但不清楚&&和之间的区别;||直到 Kaya 发表评论我才知道。

以下问题涉及两个连接器之间的区别,但主要在评论中进行:

所以这里有一些相关的问题:

  1. ;和 和有&&什么区别?
  2. 你应该分别在什么时候使用它们?看到一些用例会很高兴:如果我想运行一个命令,然后在它关闭我的计算机后,我应该选择哪个连接器?
  3. 它们的优点危害是什么?Robie Basak在对此答案的评论中提到,例如,cd /somewhere_else; rm -Rf *如果命令链中的第一个元素失败,则类似命令可能会产生破坏性后果。
  4. 如果相关,它们来自哪里?

小智 990

备忘单:

A; B    # Run A and then B, regardless of success of A
A && B  # Run B if and only if A succeeded
A || B  # Run B if and only if A failed
A &     # Run A in background.
Run Code Online (Sandbox Code Playgroud)

  • 当然,`A & B &`:在后台运行 A,然后在后台运行 B(无论成功与否)并将控制权返回给 shell。这通常与同时运行两个进程大致相同。 (31认同)
  • @user230910:那将是`(A && B) &`。 (21认同)
  • 是否可以说:只有在 a 工作时,才在后台运行 a,然后在后台运行 b?( 我猜 &&& ?) (5认同)
  • 你能参考权威文件吗?。 (5认同)
  • @JaimeHablutzel 请参阅 SHELL GRAMMAR 下的 `man bash` -> 列表 (2认同)

cho*_*oba 87

&&如果第一个命令以状态 0 退出(成功),则仅运行第二个命令。;运行这两个命令,即使第一个以非零状态退出。

你的例子&&可以等效地解释为

if sudo apt-get update ; then
    sudo apt-get install pyrenamer
fi
Run Code Online (Sandbox Code Playgroud)

  • @Private:如果第二个命令不需要前一个命令成功,您应该使用`;`。 (5认同)

Web*_*b-E 37

;不管第一个命令是否成功,Using都会执行命令。

&&仅当第一个命令成功执行(状态 0)时,Using才会执行第二个命令。

两者都用于不同的角度。就像一个更长的过程,比如说安装,你需要编译和安装它。你应该make && make install。因此,只有make成功安装才会运行。

因此,对于依赖命令,您应该使用&&.

Wring bash 或具有独立命令的命令,使用;.

所以如果你想在第一次工作失败时关闭计算机使用;,但如果想在第一次工作完全成功时启动关机使用&&


ign*_*nis 16

a ; b无论 a 的退出状态如何,都将运行 b。a && b只有在 a 成功时才会运行 b。

这对于回答前 3 个问题是必要且充分的。特别是,2 太宽泛了,不能给出“一个”明确的答案——最好的办法是根据具体情况做出决定。

至于第四个问题:它们是 Bash 语法

使用两者都没有内在危险。同样,上面的定义就足够了。这意味着如果不成功,您将&&b有意想不到的影响时编写a。恕我直言,不需要进一步的规则或解释。


小智 5

杰克的回答是非常好的经验法则。

A; B    # Run A and then B, regardless of success of A
A && B  # Run B if and only if A succeeded
A || B  # Run B if and only if A failed
A &     # Run A in background.
Run Code Online (Sandbox Code Playgroud)

我想补充一点,在某些情况下,当我们想要将它们视为一个单元或者我们不想将某些操作结果与当前 shell 耦合时,在子 shell 中使用这些命令是有意义的。

例子:


chi*_*cks 5

荣誉对杰克的cheatsheet这么说是如何工作的明确而简洁。但所有这些东西都有一个更普遍的选择原因。当您在 shell 中执行操作时,您不仅需要记住这些事实。有关更多上下文,您可能还想知道:

  • ;在 C、C++、Perl、Java、C#、awk 以及从这些语言派生的大量语言中,通常用作语句分隔符。它在所有这些方面都执行相同的功能:先做一件事,然后再做下一件事。它就像一个句子末尾的句号。
  • &在 C 中用于按位与,因此&&用于逻辑与。C 语言中的逻辑 AND 运算包括一个称为快捷方式的功能。快捷方式意味着对于 AND ,如果第一件事是假的,则没有理由检查第二件事。AND 中的单个错误项目意味着整个事情都是错误的。在 shell 中,这意味着如果第一个命令失败,它将不会进入第二个命令。或者,如果第一件事奏效,它将转到第二件事,看看它是否“可能是假的”。
  • |在 C 中用于按位 OR,因此||用于逻辑 OR。逻辑 OR 还具有快捷方式。在 OR 中,这意味着您要寻找第一个真实的东西。所以如果第一件事失败了,它会尝试第二件事。


Chr*_*bek 5

其他人都说得很好了。从实践的角度来看,我经常发现,如果您想链接命令,那么您也想知道哪里出了问题。为此,您需要了解 bash 命令中使用大括号的分组。

而不是a && b你会想写:

a || { echo "a failed" && false; } && b || echo "b failed"
Run Code Online (Sandbox Code Playgroud)