简体   繁体   English

&&:的目的是什么? 在bash脚本中

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM