`;` 和 `&&` 和 `|` 之间有区别吗?

`;` 和 `&&` 和 `|` 之间有区别吗?

当您想运行多个命令时,可以使用;,&&|

像这样:killall Finder; killall SystemUIServercd ~/Desktop/ && rm Caches或者:man grep | man cat例如。

|但是,;和之间有区别吗&&?如果是这样,有什么区别?

答案1

  • ;:以a分隔的命令; 按顺序执行。 shell 依次等待每个命令终止。

  • &&:当且仅当 command before返回退出状态为零&&时,才执行command after。&&您可以将其视为AND运算符。

  • |: 管道。在表达式中,command1 | command2command1 的标准输出通过管道连接到command2 的标准输入。

还有更多类似的控制运算符,值得一提:

  • ||||当且仅当 command before||返回非零退出状态时,command after 才会执行。您可以将其视为OR运算符。请注意,那|||是完全不同的动物。

  • &:shell&在后台执行由 终止的命令,不等待命令完成并立即返回退出代码 0。再次&与 无关&&

  • |&2>&1 |:即command1的标准输出和标准错误都通过管道连接到command2的标准输入的简写。

此外,如果您使用zshthen 您还可以使用&|或启动命令&!。在这种情况下,作业立即被拒绝,启动后它在作业表中没有位置。

答案2

考虑两个命令AB。当你写

A | B

AB并行执行,并且 的标准输出A作为 的标准输入发送B

当你写的时候

A; B

A被执行,然后B被执行(除非set -e已被使用并A以非零退出状态终止,在这种情况下,shell 在 后立即终止A)。

当你写的时候

A && B

A被执行,然后仅在成功终止(零退出状态)B时执行。A这种形式比前一种形式更安全,例如

cd some_dir && rm file*

确保&&删除正确的文件,即仅在cd成功时才删除文件。

答案3

其他答案已经解释了|,&&;,所以我将添加一些您没有明确要求的额外内容:||

A || B

A被执行,然后仅在失败B时执行。A这对于对错误情况做出反应很有用:

martin@martin ~ % rm doesnotexist 2>/dev/null || echo "failed to delete file"
failed to delete file

2>/dev/null有必要隐藏rm其自身的错误消息。)

答案4

鉴于您的实际示例,似乎没有人解释您为什么要使用每一个。我会尝试一下:

killall Finder; killall SystemUIServer

像这样的命令killall可能需要一些时间才能执行。通过使用分号,您可以同时发出两个命令,然后在等待时执行其他操作。这样您就不必等待两次(每个命令一次)。

cd ~/Desktop/ && rm Caches

您想要删除该目录~/Desktop/Caches并最终进入该目录~/Desktop。您不想做的是从当前目录中删除目录 Caches(在更改它之前)。因此&&,在执行删除命令之前, 您需要检查目录更改是否成功。

man grep | man cat

这对我来说毫无意义。该man命令不处理输入,因此通过管道传递给它不会执行任何操作。也许你的意思是

man grep || man cat

它会尝试查找 的手册页grep,如果找不到,则会显示 的手册页cat。或者可能你的意思是

man grep | cat

这将用于cat显示手册页而不是寻呼机(通常less)。将|输出重定向man到命令cat(将所有内容转储到屏幕)。这在 GUI 中很有用,您可以使用滚动条在文件中来回移动,而不是在 less 中使用键盘命令。

注意:如果您想知道; && | ||在更一般的情况下该怎么做,那么我建议查看 jimmij 的答案。我只是想解释问题示例中发生的情况。

相关内容