我遇到了一个bash脚本,它在函数
中运行以下命令set -e
rm -rf some_dir/* && :;
&& :;
在这种情况下的目的是什么?
修改
我理解它是&& true
的同义词,但现在我不承认它绕过set -e
尝试一下,我看到运行以下
#!/bin/bash -e
# false
echo false alone return 1 and fail with -e
false || true
echo "false || true return $?"
false || :;
echo "false || :; return $?"
false && true
echo "false && true return $?"
false && :;
echo "false && :; return $?"
false && :
echo "false && : return $?"
输出
false alone return 1 and fail with -e
false || true return 0
false || :; return 0
false && true return 1
false && :; return 1
false && : return 1
答案 0 :(得分:3)
它可以在手册页中找到它抑制set -e
效果的原因:
-e Exit immediately if a simple command (see SHELL GRAMMAR above) exits with a non-zero status.
The shell does not exit if the command that fails is part of the command list immediately
following a while or until keyword, part of the test in an if statement, part of a && or ||
list, or if the command's return value is being inverted via !. A trap on ERR, if set, is
executed before the shell exits.
强调:The shell does not exit if the command that fails is ... part of a && or || list
请注意,这里有一些微妙之处。常见的错误是编写像foo() { ...; rm path; #cleanup }
这样的代码,其目的是始终成功。我的意思是代码的作者甚至没有考虑foo
的退出状态,但隐含地期望是成功并且不关心{{1}的退出状态},忘记rm
返回foo
的退出状态。可能会重写代码rm
以确保rm path || :
始终成功返回,或foo
返回rm path && :
状态,但如果rm
是errexit
则不退出启用。坦率地说,它过于微妙,我相信永远不会使用set -e
的另一个原因。此外,除非您明确exit
一个脚本或return
来自函数,否则可以断言您不应该依赖代码的退出状态。
答案 1 :(得分:0)
&&
很容易解释。来自bash man
页面:
command1 && command2
当且仅当command1返回退出状态为零时才执行命令。
:
在文档中更难找到。 :
是内置的,相当于true
:
:; echo $?
0
总的来说,这个命令相当于:
递归删除目录,如果rm成功,请运行' true'。
这似乎没必要,因为&&
已经过测试过了。 rm返回true,所以有点像做true && true
。
更常见的情况是,如果您需要if/else
,只有else
可以执行某些操作,例如
if command1; then :; else command2; fi
虽然这仅在您的系统没有true
命令时才有用,但对于后来的代码读者而言,这可能更容易理解。 (或者你可以使用负面测试,而不是完全没有操作)。