&& 和 || 的混淆使用 运营商

jos*_*ain 119 shell scripting bash control-flow

我正在浏览一个/etc/rc.d/init.d/sendmail文件(我知道这几乎从未使用过,但我正在为考试而学习),并且我对&&||运算符感到有些困惑。我已经阅读了它们可以在以下语句中使用的地方:

if [ test1 ] && [ test2 ]; then
     echo "both tests are true"
elif [ test1 ] || [ test2 ]; then
     echo "one test is true"
fi
Run Code Online (Sandbox Code Playgroud)

但是,此脚本显示单行语句,例如:

[ -z "$SMQUEUE" ] && SMQUEUE="QUEUE"
[ -f /usr/sbin/sendmail ] || exit 0
Run Code Online (Sandbox Code Playgroud)

这些似乎使用&&and||运算符来根据测试得出响应,但我无法挖掘有关这些运算符的这种特殊用途的文档。任何人都可以解释这些在这种特定情况下的作用吗?

Sha*_*off 183

&&只有当左侧的退出状态为零(即真)时,才会评估右侧的。||恰恰相反:只有当左侧退出状态为非零(即假)时,它才会评估右侧。

你可以认为[ ... ]是一个有返回值的程序。如果内部的测试结果为真,则返回零;否则返回非零。

例子:

$ false && echo howdy!

$ true && echo howdy!
howdy!
$ true || echo howdy!

$ false || echo howdy!
howdy!
Run Code Online (Sandbox Code Playgroud)

额外说明:

如果你这样做了which [,你可能会看到它[实际上指向了一个程序!不过,它实际上通常不是在脚本中运行的。运行type [以查看实际运行的内容。如果WAN上使用该程序的尝试,只是给的完整路径,像这样:/bin/[ 1 = 1

  • C 程序员会发现这非常令人困惑。有 0 表示错误...而在 shellscripting 中 0 表示真实... (14认同)
  • 当你看到“X或Y”时,你测试X。如果它是真的,你已经知道“X或Y”的答案(它是真的),所以不需要测试Y。如果它是真的,你不知道回答“X或Y”,所以你确实需要测试Y。当你看到“X和Y”时,你测试X。如果它是假的,你已经知道“X和Y”的答案(它是假的),所以无需测试 Y。如果 X 为真,那么您确实需要测试 Y 以查看“X 和 Y”是否为真。 (7认同)
  • 而不是“如果左侧返回零”,我会写“如果左侧命令的退出状态为零”。我发现“返回”有点模棱两可,因为输出和退出状态都可以被视为“返回值” (4认同)
  • @Calmarius如果您习惯使用C,请考虑“return”状态,而不是布尔值,其中“return 0”表示成功。 (2认同)

use*_*073 84

这是我的备忘单:

  • "A ; B" 先运行 A 再运行 B,不管 A 是否成功
  • "A && B" 如果 A 成功就运行 B
  • "A || B" 如果 A 失败,则运行 B
  • "A &" 在后台运行 A。


Tim*_*edy 31

从上面扩展@Shawn-j-Goff 的答案,&&是逻辑与,||是逻辑或。

请参阅高级 Bash 脚本指南的这一部分。部分内容来自以下链接供用户参考。

&& 和

if [ $condition1 ] && [ $condition2 ]
#  Same as:  if [ $condition1 -a $condition2 ]
#  Returns true if both condition1 and condition2 hold true...

if [[ $condition1 && $condition2 ]]    # Also works.
#  Note that && operator not permitted inside brackets
#+ of [ ... ] construct.
Run Code Online (Sandbox Code Playgroud)

|| 或者

if [ $condition1 ] || [ $condition2 ]
# Same as:  if [ $condition1 -o $condition2 ]
# Returns true if either condition1 or condition2 holds true...

if [[ $condition1 || $condition2 ]]    # Also works.
#  Note that || operator not permitted inside brackets
#+ of a [ ... ] construct.
Run Code Online (Sandbox Code Playgroud)


小智 15

根据我的经验,我使用 && 和 || 将 if 语句缩减为一行。

假设我们正在寻找一个名为 /root/Sample.txt 的文件,那么传统的迭代在 shell 中如下所示:

if [ -f /root/Sample.txt ]
then
    echo "file found"
else
    echo "file not found"
fi
Run Code Online (Sandbox Code Playgroud)

这 6 行可以简化为一行:

[[ -f /root/Sample.txt ]] && echo "file found" || echo "file not found"
Run Code Online (Sandbox Code Playgroud)

当运行几次迭代来设置变量或创建文件等时,使用单行 if 函数会更轻松,脚本看起来更流畅,唯一的缺点是从一次迭代中实现多个命令变得有点困难,但是你可以使用函数。