[英]What is the purpose of && :; in bash scripts
I've come across a bash script which runs the following command within a function 我遇到了一个bash脚本,该脚本在一个函数中运行以下命令
set -e
rm -rf some_dir/* && :;
What is the purpose of && :;
&& :;
的目的是什么? in this context? 在这种情况下?
Edit: 编辑:
I understand that it's synonym to && true
, but now I don't undertand why it bypass set -e
我知道这是
&& true
的同义词,但是现在我不明白为什么它绕过set -e
Trying it out I see that running the following 尝试一下,我看到运行以下命令
#!/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 $?"
Outputs 产出
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
The reason it suppresses the effect of set -e
can be found in the man page: 它抑制
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.
For emphasis: The shell does not exit if the command that fails is ... part of a && or || list
需要强调的是:
The shell does not exit if the command that fails is ... part of a && or || list
The shell does not exit if the command that fails is ... part of a && or || list
Note that there is some subtlety here. 注意这里有些微妙之处。 A common error is to write code like
foo() { ...; rm path; #cleanup }
一个常见的错误是编写类似
foo() { ...; rm path; #cleanup }
foo() { ...; rm path; #cleanup }
foo() { ...; rm path; #cleanup }
in which the intent is to always be successful. foo() { ...; rm path; #cleanup }
,目的是永远成功。 By which I mean that the author of the code didn't really even think about the exit status of foo
but implicitly expects is to succeed and doesn't care about the exit status of rm
, forgetting that foo
returns the exit status of rm
. 我的意思是,代码的编写者甚至没有真正考虑过
foo
的退出状态,而是隐含地期望成功并且不关心rm
的退出状态,而忘记了foo
返回rm
的退出状态。 The code might be re-written rm path || :
可能会将代码重写为
rm path || :
rm path || :
to ensure that foo
always returns successfully, or rm path && :
to return the status of rm
but not exit if errexit
is enabled. rm path || :
确保foo
总是成功返回,或rm path && :
返回rm
的状态,但如果启用errexit
则不退出。 Frankly, it's too subtle and I believe one additional reason for never using set -e
. 坦白说,它太微妙了,我相信永远不要使用
set -e
另一个原因。 Also, an argument could be made that you should never rely on the exit status of code unless you explicitly exit
a script or return
from a function. 此外,可能会提出一个论点,即除非您明确
exit
脚本或从函数return
,否则您永远不应依赖代码的退出状态。
The &&
is easy to explain. &&
很容易解释。 From the bash man
page: 从bash
man
页:
command1 && command2
command2 is executed if, and only if, command1 returns an exit status of zero.
仅当command1返回退出状态为零时,才能执行command2。
:
is harder to find in the docs. :
很难在文档中找到。 :
is a builtin that is equivalent to true
: :
是一个等效于true
的内置函数:
:; echo $?
0
So overall, this command equates to: 因此,总的来说,此命令等于:
Recursively remove the directory, and if the rm is successful, run 'true'.
递归删除目录,如果rm成功,则运行'true'。
It's seems unnecessary though, since &&
has already 'tested' that rm is returning true, so it's a bit like doing true && true
. 但是,这似乎没有必要,因为
&&
已经“测试”了rm是否返回true,所以有点像做true && true
。
More commonly this is used when you want an if/else
where only the else
does something, eg 更常见的是在需要
if/else
情况下使用else
来做某事,例如,
if command1; then :; else command2; fi
Though this is only useful if your system doesn't have a true
command, which is arguably easier for a later reader of the code to understand. 尽管这仅在您的系统没有
true
命令时才有用,但是对于以后的代码阅读者来说,这无疑会更容易。 (Or you could use a negative test and not bother with a no-op at all). (或者,您可以使用否定测试,而根本不用操心)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.