Answers:
用这一行:
command1 && command2
当(仅当)command1返回退出状态为零时,command2将被执行,而在此行中:
command1 ; command2
无论command1和command2都将执行。分号使您可以在一行上键入许多命令。
您可以自己尝试区别:
ls /invalid/path && echo "hello!"
由于/ invalid / path不存在,所以ls无法显示目录列表。它将失败,并显示错误消息:“ ls:/ invalid / path:没有这样的文件或目录”。
该命令的后半部分(回声“ hello!”)甚至不会执行,因为前半部分失败了。
ls /invalid/path ; echo "hello!"
出现与以前相同的错误消息,但是这次执行第二部分!
ls:/ invalid / path:没有这样的文件或目录
!
为什么这有用?
假设您要提取一个名为archive.tar.gz的文件,则
可以使用命令tar zxvf archive.tar.gz && rm archive.tar.gz
。
如果出于任何原因提取存档失败,则不会执行第二部分!您可以再试一次。
如果使用; 在相同情况下,归档文件将被删除,您无法重试。
&&
是AND
,这意味着第二条命令仅在第一个命令返回true(无错误)时才会执行。
AND
执行,如果第一个等于第二个参数变得无关紧要false
等底层代码被优化,直到它知道第一个是什么推迟的第二个参数的评估。
&&
只是一个二进制运算符,一个函数。唯一的“特殊”问题是它是后缀表示法(无论如何对于大多数此类运算符都是标准的)和第二个操作数的延迟执行。延迟执行的确使它能够被用作在上下文中可以在概念上视为if
语句的东西,但这并不能消除它的最初预期用法在实际语句的条件之内的事实。此处的使用实际上更多是“ hack”。if
a && b || c = (a && b) || c
。简单的评估顺序。那里真的没有任何神秘之处。如果您像典型功能一样编写它们,则看起来就像or(and(a, b), c)
。此逻辑在if
条件内以及直接在命令行中输入时都是相同的,因为&&
和||
是运算符,它们接受两个操作数,然后返回另一个。
更新:我已作为脚本添加了一些可能的陷阱:
因为没有人提到“ ||”,所以我会
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