以下链接命令方法之间有什么区别?
cmd1; cmd2
cmd1 && cmd2
#1 楼
假设存在command1 && command2
。在这种情况下,仅当command2
返回零退出状态时,才会执行command1
。;
只是命令分隔符。因此,无论返回的command2
为何,都将执行command1
。$> [[ "a" = "b" ]] && echo ok
$> [[ "a" = "b" ]]; echo ok
ok
#2 楼
cmd1; cmd2
执行cmd1
,然后执行cmd2
,无论如何。它完全等效于将cmd1
和cmd2
放在单独的行上¹。该复合命令的返回状态为cmd2
。cmd1 && cmd2
执行cmd1
。然后,如果cmd1
的退出状态为零,则执行cmd2
。此复合命令的返回状态为cmd1
(如果它不为零)(因此cmd2
未运行),否则为cmd2
(如果已运行)。返回页首if cmd1; then cmd2; fi
与cmd1 && cmd2
等效。主要区别在于,如果if
返回非零状态,则带有cmd1
的版本将返回0。命令返回0表示成功,并且返回非零错误代码(介于1和255之间,通常介于1和125之间)因为较高的值具有其他含义)表示失败。因此,
cmd1; cmd2
的意思是“无论如何都按顺序执行这些命令”,而cmd1 && cmd2
的意思是“执行这些命令,但是如果第一个命令失败,则立即停止。” 您可以告诉Shell输入“ exit on错误”模式,方法是运行
set -e
。在这种模式下,除了条件构造(&&
或||
的左侧,if
和while
的条件部分)外,任何命令返回非零状态后,shell都会退出。因此,在set -e
下,;
(或换行符)实际上等效于&&
²。¹就控制流而言,即。换行和分号的执行方式完全相同,但它们的解析方式却不完全相同,例如
alias ls=true; ls
执行ls
而不执行true
,因为解析器在执行别名定义之前先对ls
执行别名解析。 ¹这并不是说如果添加了
&&
,就可以用;
盲目替换set -e
。例如,;
的优先级低于&&
,因此cmd1 && cmd2 || cmd3
等同于set -e; { cmd1; cmd2; } || cmd3
。另外,set -e
与子外壳之间的交互很差-详细信息会使该答案偏离的太远了。 评论
“因为更高的值具有其他含义”是什么意思?如果我在编写自己的程序,是否有任何标准的错误命名(编号?)约定?
– rahmu
2012年4月23日在9:42
@rahmu Shell使用错误代码126和127指示根本无法启动该程序,并使用128 + N指示该程序以信号N终止。因此,从Shell出发,唯一清楚地显示该程序的状态代码跑到完成是0到126(如果确实要使读者感到困惑,则为128)。
–吉尔斯'所以-不再是邪恶的'
2012年4月23日在17:02
@吉尔斯:我完全不同意最后一句话。试试echo $(set -e; {false;(exit 2)} && true; echo $?)vs echo $$(set -e; {false &&(exit 2)} && true; echo $?);)
–StéphaneGimenez
2012年4月23日在18:59
@StéphaneGimenez好的,是的,将-e和subshell一起设置可能很时髦。
–吉尔斯'所以-不再是邪恶的'
2012年4月23日20:02在
注意:cmd1; cmd2不一定与cmd1
–StéphaneChazelas
17年1月11日在10:26
#3 楼
无论第一行是否成功,第一行都会一个接一个地执行命令。第二行是shell逻辑的示例:仅在第一个命令成功的情况下才执行第二个命令。这是因为&&
是逻辑and
。因此,如果第一个命令失败,则已知整行的逻辑状态为假,因此无需评估第二个命令。#4 楼
更实际的是,cd /backup/old; rm -rf -- *
和
cd /backup/old && rm -rf -- *
之间是有区别的。除了这是一种愚蠢的方法外,第一个将删除整个文件系统(或$ HOME,取决于其调用方式),因为无论
rm
是否成功,它都会运行cd
。评论
虽然您的答案是正确的,但是如果用户运行它来亲自查看差异,则很危险。为什么不“回声某事”呢?
–兰迪·斯蒂格鲍尔(Randy Stegbauer)
2012年4月23日在17:46
我相信人们不要做明显的愚蠢的事情。这是我直接听到的+/-示例。
–Reactormonk
2012年4月23日在22:56
@RandyStegbauer因为执行此操作的人员不应该在其文件系统中拥有文件。
– alexg
14-10-15在8:59
评论
同样,command1 ||仅当command1返回非零退出状态时,才能使用command2运行command2。
– hammar
2012年4月22日20:19在
请注意,完整表达式的返回值是最后执行的命令的返回值。
–StéphaneGimenez
2012年4月22日在22:05
实际上很奇怪..如果command1返回零,那么执行command2吗?考虑到惰性计算,&&甚至在第一个参数已经为0时也不应查看第二个参数-无论如何结果将为0。
–科尼拉克
2012年4月24日在8:57
@Konerak:对于退出代码,0表示成功,而其他则为假,则为true,因此与“普通”布尔值相比,它有点相反。
– hammar
2012年4月27日在20:25
@hammar似乎很不幸。更为合理的选择是0 ||。 next_step表示上一步的成功,符合逻辑或的惰性评估。
–江强
17-10-17在17:28