[英]What is the purpose of && :; in bash scripts
我遇到了一个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
它抑制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
The shell does not exit if the command that fails is ... part of a && or || list
注意这里有些微妙之处。 一个常见的错误是编写类似foo() { ...; rm path; #cleanup }
foo() { ...; rm path; #cleanup }
foo() { ...; rm path; #cleanup }
,目的是永远成功。 我的意思是,代码的编写者甚至没有真正考虑过foo
的退出状态,而是隐含地期望成功并且不关心rm
的退出状态,而忘记了foo
返回rm
的退出状态。 可能会将代码重写为rm path || :
rm path || :
确保foo
总是成功返回,或rm path && :
返回rm
的状态,但如果启用errexit
则不退出。 坦白说,它太微妙了,我相信永远不要使用set -e
另一个原因。 此外,可能会提出一个论点,即除非您明确exit
脚本或从函数return
,否则您永远不应依赖代码的退出状态。
&&
很容易解释。 从bash man
页:
command1 && command2
仅当command1返回退出状态为零时,才能执行command2。
:
很难在文档中找到。 :
是一个等效于true
的内置函数:
:; echo $?
0
因此,总的来说,此命令等于:
递归删除目录,如果rm成功,则运行'true'。
但是,这似乎没有必要,因为&&
已经“测试”了rm是否返回true,所以有点像做true && true
。
更常见的是在需要if/else
情况下使用else
来做某事,例如,
if command1; then :; else command2; fi
尽管这仅在您的系统没有true
命令时才有用,但是对于以后的代码阅读者来说,这无疑会更容易。 (或者,您可以使用否定测试,而根本不用操心)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.