shell命令中“ &&”的目的是什么?


Answers:


398

&&可让您根据上一个命令是否成功完成执行某些操作-这就是为什么您倾向于将其链接为的原因do_something && do_something_else_that_depended_on_something


391

此外,您还具有||逻辑上的“或”,也;仅仅是分隔符,它并不关心命令之前发生的情况。

$ false || echo "Oops, fail"
Oops, fail

$ true || echo "Will not be printed"
$  

$ true && echo "Things went well"
Things went well

$ false && echo "Will not be printed"
$

$ false ; echo "This will always run"
This will always run

有关此操作的一些详细信息,可以在Bash手册中的“命令列表”中找到。


5
也许您想添加false && echo "Will not be printed"
MTSan

112

命令行-目的是&&什么?

在外壳中,当您看到

$ command one && command two

目的是&&仅在第一个命令成功时才执行紧随其后的命令。这是Posix shell的惯用用法,不仅在Bash中发现。

如果第一个进程失败,它旨在阻止第二个进程的运行。

您可能会注意到我使用了“意图”一词-这是有充分理由的。并非所有程序都具有相同的行为,因此,要使其正常工作,您需要阅读文档以及必要时了解源代码,以了解程序认为的“故障”及其处理方式。

您的外壳将返回值0表示为true,将其他正数表示为false

程序在退出时返回一个信号。如果成功退出,则应返回0;否则,请返回大于零。这允许进程之间的通信量有限。

&&被称为AND_IFPOSIX壳语法,这是一个的一部分and_or列表的命令,其中还包括||其为OR_IF具有相似的语义。

语法符号,从文档中引用:

%token  AND_IF    OR_IF    DSEMI
/*      '&&'      '||'     ';;'    */

语法(也从文档中引用)表明可以将任意数量的AND_IFs(&&)和/或OR_IFs(||)串在一起(如and_or递归定义):

and_or           :                         pipeline
                 | and_or AND_IF linebreak pipeline
                 | and_or OR_IF  linebreak pipeline

两个运算符具有相同的优先级,并且从左到右进行评估(它们是左关联的)。正如文档所说:

一个AND-OR列表是由运算符分隔的一个或多个管道的序列"&&""||"

列表是一个或多个的序列AND-OR列表分离由运营商';''&'和任选地被封端';''&'或。

运算符"&&""||"应当具有同等的优先级,并且应使用左联想进行评估。例如,以下两个命令仅将bar写入标准输出:

$ false && echo foo || echo bar
$ true || echo foo && echo bar
  1. 在第一种情况下,false是以以下状态退出的命令: 1

    $ false
    $ echo $?
    1

    这意味着echo foo不运行(即短路echo foo)。然后echo bar执行命令。

  2. 在第二种情况下,true退出,代码为 0

    $ true
    $ echo $?
    0

    因此echo foo不执行,然后echo bar执行。


31

“ &&”的一个很常见的用法是使用自动工具编译软件。例如:

./configure --prefix=/usr && make && sudo make install

基本上,如果配置成功,则运行make进行编译,如果成功,则以root用户运行make来安装程序。当我最确定一切都会正常工作时,我会使用它,它使我能够做其他重要的事情,例如查看stackoverflow而不是“监视”进度。

有时候我真的被带走了...

tar xf package.tar.gz && ( cd package; ./configure && make && sudo make install ) && rm package -rf

例如,从头开始制作linux时,我会这样做。


2
REPL很好,但是对于脚本,我更喜欢set -o errexitBash。
富兰克林·于

19

&&将命令串在一起。后续命令仅在前面的命令成功的情况下执行。

同样,||如果前面的命令失败,将允许连续命令执行。

请参阅Bash Shell编程


8

参见示例:

mkdir test && echo "Something" > test/file

命令行管理程序将尝试创建目录test,然后仅在成功执行后才尝试在其中创建文件。

因此,如果其中一个步骤失败,则可以中断一系列步骤。


8

如果第一条语句成功结束,则执行第二条语句。就像if语句:

 if (1 == 1 && 2 == 2)
  echo "test;"

它首先尝试1 == 1,如果是,则检查2 == 2


1
有人可以解释为什么对用户绊脚石这个问题不满意吗?
user3243242

1
@ user3243242没错,只是一个不好的例子来说明&&
dan

这是对if测试如何在bash中工作的深刻见解。我从未想过它像是一串比较命令,当其中任何一个失败时就会中断。所以您得到了我的支持:)
PiRK

1
结果是您可以通过使用||,链接命令直到其中之一成功获得相反的行为: eei || leu || uie || echo prout3 || echo "never executed"
PiRK

7

command_1 && command_2:仅在成功执行command_1时才执行command_2。

command_1 || command_2:仅在未成功执行command_1时执行command_2。

感觉与以主流编程语言执行“ if”条件的方式类似,例如,if (condition_1 && condition_2){...}如果condition_1为条件,则将省略condition_2 false中的if (condition_1 || condition_2){...}条件,如果condition_1是,则将省略condition_2中的条件true。瞧,这与您编码时使用的技巧相同:)


我不知道您的意思是“完全相反”,而是$ echo'1'|| 回声“ 2”仅打印“ 1”。和$ wrong_command || 回声“ 2”将显示错误消息,并在下一行显示“ 2”。您能否再解释一下您认为错在哪里?
Xiaonin Li

老兄,昨天我当然太累了。抱歉,这只是我的意思://如果您要我投票,我需要在您的答案中编辑一些内容(使您的答案为0,现在stackoverflow要求进行编辑,所以我不能这样做)
大约

@Arount,没关系,不用担心。所以我刚刚提交了修改。所以您现在可以删除不赞成票吗?
Xiaonin Li

是的,再次,对不起,真的
Arount

0
####################### && or (Logical AND) ######################
first_command="1"
two_command="2"

if [[ ($first_command == 1) && ($two_command == 2)]];then
 echo "Equal"
fi

当程序检查命令是否存在时,程序将创建一个称为退出代码的数字,如果两个条件均成立,则退出代码为零(0),否则,退出代码为正数。仅当显示退出代码为零(0)时才显示Equal,这意味着两个条件都成立。


欢迎使用stackoverflow。在此处发布之前,请确保您的代码段有效。您必须纠正它if [[ ($first_command == "1") && ($two_command == "2") ]];then echo "Equal"; fi
Zheng Qu

1
谢谢@ZhengQu的命令,它已经完成了。
阿敏
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.