“ &&”和“;”之间是否有区别 标准BASH终端中的符号?


56

它们似乎都向BASH发出信号,要求它们从符号后面的另一个命令开始,但是有明显区别吗?

Answers:


75

用这一行:

command1 && command2

当(仅当)command1返回退出状态为零时,command2将被执行,而在此行中:

command1 ; command2

无论command1和command2都将执行。分号使您可以在一行上键入许多命令。


1
有趣!我以为这可能是一种更舒适的方法。谢谢!

42

您可以自己尝试区别:

  1. ls /invalid/path && echo "hello!"
    由于/ invalid / path不存在,所以ls无法显示目录列表。它将失败,并显示错误消息:“ ls:/ invalid / path:没有这样的文件或目录”。
    该命令的后半部分(回声“ hello!”)甚至不会执行,因为前半部分失败了。

  2. ls /invalid/path ; echo "hello!"
    出现与以前相同的错误消息,但是这次执行第二部分
    ls:/ invalid / path:没有这样的文件或目录

为什么这有用?
假设您要提取一个名为archive.tar.gz的文件,则
可以使用命令tar zxvf archive.tar.gz && rm archive.tar.gz
如果出于任何原因提取存档失败,则不会执行第二部分!您可以再试一次。

如果使用; 在相同情况下,归档文件将被删除,您无法重试。


8

&&AND,这意味着第二条命令仅在第一个命令返回true(无错误)时才会执行。


1
&&是一个“ then”(不是“ and”)...请参阅我的回答
Peter.O 2011年

2
@fred我要说这是短路评估“和” -如果第一部分不为真,则它知道总结果必须为假,因此它跳过了第二部分。但请同意,在这种情况下,将其视为“那么”的意义很少。
jg-faustus

2
@fred尽管从概念上讲可能更容易理解,但我不同意您的说法。这个想法很简单,就是用任何 AND执行,如果第一个等于第二个参数变得无关紧要false等底层代码被优化,直到它知道第一个是什么推迟的第二个参数的评估。
Ward Muylaert

2
@fred我不确定该示例试图说明什么。&&只是一个二进制运算符,一个函数。唯一的“特殊”问题是它是后缀表示法(无论如何对于大多数此类运算符都是标准的)和第二个操作数的延迟执行。延迟执行的确使它能够被用作在上下文中可以在概念上视为if语句的东西,但这并不能消除它的最初预期用法实际语句的条件之的事实。此处的使用实际上更多是“ hack”。if
Ward Muylaert

3
@fred当然它不是三元运算符,它只是两个运算的继承a && b || c = (a && b) || c。简单的评估顺序。那里真的没有任何神秘之处。如果您像典型功能一样编写它们,则看起来就像or(and(a, b), c)。此逻辑在if条件内以及直接在命令行中输入时都是相同的,因为&&||运算符,它们接受两个操作数,然后返回另一个。
Ward Muylaert

8

更新:我已作为脚本添加了一些可能的陷阱:

因为没有人提到“ ||”,所以我会

Update2:此处
&&的一些重要重新措辞就像“ if”语句的“ then”,它响应“ true”

|| 是不是像一个“如果” statment ..的“其他”
|| 就像是“ if”语句的“ then”,它响应“ false”

更具体地说,&&测试$?返回前一个 最近执行的语句的值,并将控制权直接传递给&& ...之后的语句或子外壳,如果$?是真的。

|| 相似,通常在&&语句后出现,但是它会测试前一个最近执行的语句 是否有错误的返回值($?),Nota Bene!请注意!! ...如果该predecing语句是&&语句,当您期望它为true时会重新运行false,则|| 将对错误做出响应,因此在同一行上将两者混用可能会有风险

我要提出的主要观点是关于我犯的一个错误。即:
## [[条件]] && A || 乙
不表现得像一个C / C ++式三元。即:
//(条件)?A:B
有关“ A”的“意外”结果的示例,请参见以下脚本

基本测试以及&&和|| 声明必须全部在同一行...


运行此脚本,查看使用&&和||时哪里可能出错。
最近执行的语句可能不是你所期望的一个..

[[条件]] &&回声|| 回声再见....通常是安全的,
因为格式正确的回声将返回true。
但是如何访问不退出的文件呢?

#!/bin/bash
#
# "as expected" return codes" means: expected to behave like a normal AND / OR  contition test
#
if [[ "$1" != "" ]] ; then exit $1; fi # recursive call to return an arbitary $? value (decimal)
echo
echo 'test 1: All return codes are "as expected"'
echo  ======
 ((1==1)) && echo  " ((1==1)) rc=$? ..&&.. condition is true" || echo  " ((1==1)) rc=$? ..||.. condition is false"
  $0  0   && echo "  \$0  0   rc=$? ..&&.. condition is true" || echo "  \$0  0   rc=$? ..||.. condition is false"
 ((1!=1)) && echo  " ((1!=1)) rc=$? ..&&.. condition is true" || echo  " ((1!=1)) rc=$? ..||.. condition is false"
  $0  1   && echo "  \$0  1   rc=$? ..&&.. condition is true" || echo "  \$0  1   rc=$? ..||.. condition is false"
echo
echo 'test 2: Now throw in some "unexpected" errors into the first of the &&/|| pair' 
echo  ======
 ((1==1)) && (echo  " ((1==1)) rc=$? ..&&.. condition is true"; $0 1)  || echo  " ((1==1)) rc=$? ..||.. condition is false"
  $0  0   && (echo "  \$0  0   rc=$? ..&&.. condition is true"; $0 2)  || echo "  \$0  0   rc=$? ..||.. condition is false"
 ((1!=1)) && (echo  " ((1!=1)) rc=$? ..&&.. condition is true"; $0 3)  || echo  " ((1!=1)) rc=$? ..||.. condition is false"
  $0  1   && (echo "  \$0  1   rc=$? ..&&.. condition is true"; $0 4)  || echo "  \$0  1   rc=$? ..||.. condition is false"
echo
echo 'test 3: Now swap the order of && and || statements, using "as expected" return codes'
echo  ======
 ((1==1)) || echo  " ((1==1)) rc=$? ..||.. condition is true" && echo  " ((1==1)) rc=$? ..&&.. condition is false"
  $0  0   || echo "  \$0  0   rc=$? ..||.. condition is true" && echo "  \$0  0   rc=$? ..&&.. condition is false"
 ((1!=1)) || echo  " ((1!=1)) rc=$? ..||.. condition is true" && echo  " ((1!=1)) rc=$? ..&&.. condition is false"
  $0  1   || echo "  \$0  1   rc=$? ..||.. condition is true" && echo "  \$0  1   rc=$? ..&&.. condition is false"
echo
echo 'test 4: With the order of && and || statements still swapped, introduce "unexpected" errors into the first of the &&/|| pair' 
echo  ======
 ((1==1)) && (echo  " ((1==1)) rc=$? ..&&.. condition is true"; $0 1)  || echo  " ((1==1)) rc=$? ..||.. condition is false"
  $0  0   && (echo "  \$0  0   rc=$? ..&&.. condition is true"; $0 2)  || echo "  \$0  0   rc=$? ..||.. condition is false"
 ((1!=1)) && (echo  " ((1!=1)) rc=$? ..&&.. condition is true"; $0 3)  || echo  " ((1!=1)) rc=$? ..||.. condition is false"
  $0  1   && (echo "  \$0  1   rc=$? ..&&.. condition is true"; $0 4)  || echo "  \$0  1   rc=$? ..||.. condition is false"

exit 


1

尝试

false &&回声“你好”

错误的; 回声“你好”

看到不同


0

之后的命令(脚本的情况下的功能)&&将根据第一个命令的RETVAL(脚本的情况下的功能)执行。如果成功,它将强制第一个命令返回值0。我们可以检查返回值以执行更多命令。

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.