我浏览了一个/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


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

[ -z "$SMQUEUE" ] && SMQUEUE="QUEUE"
[ -f /usr/sbin/sendmail ] || exit 0


这些似乎正在使用&&||运算符基于测试得出响应,但是我无法从这些运算符的这种特殊用法中提取文档。谁能解释在特定情况下这些工具的作用?

#1 楼

仅当左侧的退出状态为零(即true)时,才会评估&&的右侧。 ||相反:仅当左侧出口状态为非零(即false)时,它才会评估右侧。

您可以将[ ... ]视为具有返回值的程序。如果内部测试的结果为true,则返回零;否则,返回零。它会返回非零值。

示例:

$ false && echo howdy!

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

$ false || echo howdy!
howdy!


附加说明:

如果执行which [,则可能看到[实际上指向程序!但是,通常它实际上不是在脚本中运行的那个。运行type [以查看实际运行的内容。如果您想尝试使用该程序,只需给出完整的路径,例如:/bin/[ 1 = 1

评论


看到“ X或Y”时,您将测试X。如果是,则已经知道“ X或Y”的答案(是),因此无需测试Y。如果是,则您不知道X。答案为“ X或Y”,因此您确实需要测试Y。看到“ X和Y”时,您将测试X。如果它为假,则您已经知道了“ X和Y”的答案(它为假),因此不需要测试Y。如果X为true,那么您确实需要测试Y以查看“ X and Y”是否为true。

– David Schwartz
2011年11月16日,下午3:41

我会写“如果左侧命令的退出状态为零”,而不是“如果左侧返回零”。我发现“返回”有点模棱两可,因为输出和退出状态都可以视为“返回值”

–格伦·杰克曼
2011年11月16日14:36

在许多情况下,您不仅可以“考虑[...]作为程序”。通常在文件/ bin / [或/ usr / bin / [中。

– Lance E Sloan先生
16-10-28在16:39

C程序员会发现这个超级混乱。那里0表示错误...而在shellscript中0表示正确...

–卡尔马留斯
17年8月15日在9:37

@Calmarius如果您习惯了C,请考虑返回状态,而不是布尔值,其中return 0表示成功。

– TimD1
19年7月9日在18:14

#2 楼

这是我的备忘单:


“ A; B”先运行A,然后再运行B,无论A是否成功
如果A成功,则运行A && B“
“ A || B”如果A失败则运行B
“ A&”在后台运行A。


评论


在运行的JavaScript中,有一些有趣的Lambda微积分并行处理(按顺序定义变量); “ left(aka true)” :( a => b => a)。 “正确(即假)” :( a => b => b)。 “ A; B”“然后”(a => b =>(()=> b())(a()))。 “ A && B”“如果没有其他(何时)”(a => b => a()(()=>正确)(b))。 “ A || B”“否则,如果没有(除非)”(a => b => a()(b)(()=>正确))。 “ a && b || c”“ ifThenElse”(a => b => c =>(除非(when(a)(b))(c))())。

–德米特里
17年7月15日在4:53



请注意,在bash中,左边是类似0 /空字符串,右边是其他所有东西。

–德米特里
17年7月15日在5:00

#3 楼

为了从上面扩展@ Shawn-j-Goff的答案,&&是逻辑AND,||是逻辑OR。

请参阅《高级Bash脚本指南》的这一部分。链接中的某些内容供用户参考,如下所示。

&&
AND

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.


|||
OR

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.


#4 楼

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

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

if [ -f /root/Sample.txt ]
then
    echo "file found"
else
    echo "file not found"
fi


这6行可以减少为一行:

[[ -f /root/Sample.txt ]] && echo "file found" || echo "file not found"


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

评论


这很酷。让我想起objc代码(a == b)?val = 1:val = 2;

– GeneCode
17年8月29日在4:13



我想在后台使用“&”运行进程时如何使用此命令?我收到./someScript.sh&&& echo'ok'||的语法错误。回声'ko'

–凯蒂
18年3月20日在22:54

格式:foo && bar || baz,如果foo成功,则bar失败,baz将运行,因此它与if语句有细微差别。

–马特尔
20-3-21在14:28

#5 楼

有一个“捷径”的概念。

评估(expr1 && expr2)时-仅当expr2评估为“ true”时,才评估exp1。这是因为expr1expr2都必须为true才能使(expr1 && expr2)为真。如果expr1的值为“ false”,则expr2未被评估(快捷方式),因为(expr1 && expr2)已经是“ flase”。

请尝试以下操作-假设文件F1存在且文件F2不存在:

( [ -s F1 ] && echo "File Exists" )  # will print "File Exists" - no short cut
( [ -s F2 ] && echo "File Exists" )  # will NOT print "File Exists" - short cut


||(或)类似-但短接方式相反。

评论


该逻辑通常称为“短路”。我从未见过使用“捷径”这个词。我提到这一点是为了帮助查找参考。

– Lance E Sloan先生
16-10-28在16:42

#6 楼

Shawn J. Goff的答案中的示例是正确的,但解释却相反。请检查:


仅当左侧的出口状态为NONZERO时,才会评估&&的右侧。 ||相反:只有在左侧出口状态为零时,它才会评估右侧。


评论


您知道,对于shell,零退出代码的值为true,因此&&左侧的非零退出代码会导致整个表达式返回false?

–反模式
16-9-29在15:25



有人不批准您的修改,因为这不是您的答案。如果您认为某个答案不正确,则应该对其投下反对票,并可能发表评论;如果您认为需要更改,则应发表评论。编辑是为了纠正不会改变答案含义的语法,格式和拼写错误。

– techraf
16-9-29在15:41



@countermode对不起,您是对的,我认为在Linux中零=假,非零=真(例如在C和许多其他语言/环境/平台中)。造成误解,我深表歉意。

– Try2Help
16-10-5在10:16