'&&' 和 ';' 之间有区别吗 标准 BASH 终端中的符号?

59 command-line bash

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

小智 81

有了这条线:

command1 && command2
Run Code Online (Sandbox Code Playgroud)

当(且仅当)command1 返回退出状态零时,才会执行 command2,而在这一行中:

command1 ; command2
Run Code Online (Sandbox Code Playgroud)

无论如何,command1 和 command2 都将被执行。分号允许您在一行中键入多个命令。


Ken*_*ert 43

您可以自己尝试不同之处:

  1. ls /invalid/path && echo "hello!"
    由于 /invalid/path 不存在, ls 无法向您显示目录列表。它将失败并显示错误消息:“ls: /invalid/path: No such file or directory”。
    下半场的命令(回声“你好!”)是从来没有执行,因为上半年的失败。

  2. ls /invalid/path ; echo "hello!"
    和之前一样出现同样的错误信息,但是这次,第二部分被执行了
    ls: /invalid/path: 没有那个文件或目录
    你好!

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

如果你使用; 在同样的情况下,存档被删除,你不能再试一次。


War*_*ert 8

&&is AND,这意味着第二个命令只会在第一个返回 true (没有错误)时执行。

  • @fred当然不是三元运算符,它只是两个操作的连续性`a && b || c = (a && b) || c`。简单的评估顺序。那里真的没有什么神秘之处。如果你将它们写成你的典型函数,它看起来就像 `or(and(a, b), c)`。这个逻辑在 `if` 条件语句中以及直接输入命令行时都是一样的,因为 `&&` 和 `||` 是 *operators*,它们接受两个操作数并返回另一个。 (3认同)
  • @fred 我会说这是一个 ["and" 与短路评估](http://en.wikipedia.org/wiki/Short-circuit_evaluation) - 如果第一部分不正确,它知道总结果必须是假的,所以它跳过了第二部分。但是同意将其视为“然后”在这种情况下很少会产生很大差异。 (2认同)
  • @fred 虽然从概念上讲,这样理解可能更容易,但我不同意你的说法。这个想法很简单,对于 *any* `AND` 执行,如果第一个参数等于 `false`,则第二个参数变得无关紧要,因此底层代码得到优化以推迟对第二个参数的评估,直到它知道第一个参数是什么。 (2认同)
  • @fred 我不确定这个例子试图说明什么。`&&` 只是一个二元运算符,一个函数。唯一的“特殊”是它是中缀符号(无论如何这是大多数此类运算符的标准)和第二个操作数的延迟执行。延迟执行确实使它能够被用作在概念上可以被视为“if”语句*在这种情况下*的东西,但这并没有消除它最初的预期用途是*在*内的事实实际`if`语句的条件。这里的使用实际上更像是一种“黑客”。 (2认同)

Pet*_*r.O 8

更新:我添加了脚本来突出一些可能的陷阱:

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

更新2:这里一些重要的重新措辞
&&就像一个“if”语句的“then”,它响应“true”

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

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

|| 是相似的,而且经常看到下面的一个&&的语句,但它测试的从返回值($?)之前的 最近执行的语句... NB!,诺塔贝尼!请注意!.... 如果前面的语句是一个 && 语句,当您期望它为真时返回 false,则 || 会响应错误,所以在同一条线上混合可能有风险

我试图提出的主要观点与我犯的错误有关。即:
## [[条件]] && A || B
is not不像 C/C++ 风格的三元。即:
//(条件)?A : B
有关“A”的“意外”结果示例,请参阅下面的脚本

基本测试和 && 和 || 语句必须都在同一行...


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

[[条件]] && echo 你好 || echo Goodbye .... 通常是安全的,
因为格式良好的 echo 将返回 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 
Run Code Online (Sandbox Code Playgroud)