在 bash 脚本中哪个更惯用:`|| 真`或`|| :`?

Mar*_*off 53 shell bash

我没有做太多的 shell 脚本,所以当我阅读文档git submodule时我有点惊讶,我看到了他们在这个文档中使用的语法:

任何子模块中命令的非零返回都会导致处理终止。这可以通过添加|| :到命令的末尾来覆盖。

我不得不查找这|| :是强制命令成功退出的简写。每当我必须成功退出命令时,我都会使用|| true. 被|| :认为更地道?

Sté*_*las 50

true没有内置到 Bourne shell 中。:一直是(这是在#介绍之前输入评论的方式)。

这一点,因为它是短到类型可能是主要原因人喜欢:true

请注意 POSIX shell 的另一个区别(对于bash,仅在 POSIX 模式下):whiletrue是常规内置(甚至不必内置),:特殊内置。这有一些影响,其中大部分不太可能在这种特殊情况下产生任何影响:

  • 如果:命令失败,包括由于重定向失败,则会导致 shell 退出。实际上,除非您将重定向传递给:

    $ sh -c ': > /   ; echo HERE'
    sh: 1: cannot create /: Is a directory
    $ sh -c 'true > /; echo HERE'
    sh: 1: cannot create /: Is a directory
    HERE
    
    Run Code Online (Sandbox Code Playgroud)
  • in var=value :,var仍然设置为valueafter:返回,而不是在以下情况下true

    $ var=1; var=2 :   ; echo "$var"
    2
    $ var=1; var=2 true; echo "$var"
    1
    
    Run Code Online (Sandbox Code Playgroud)

还要注意的是|| true在贝壳工作rccsh家庭而不是|| :(但不取消set -ecsh)。

|| :不一样:。它意味着或以:其他方式运行(即,如果前面的管道失败)。

set -e
false
Run Code Online (Sandbox Code Playgroud)

会导致 shell 由于set -e(又名errexit选项)退出并false具有非零(失败)退出状态。该set -e效果被取消如果返回一个非0状态被用作命令条件等在:

if false; then ...
while false; do ...
false && : ...
false || : ...
Run Code Online (Sandbox Code Playgroud)

false && :只取消set -efalse || :取消效果set -e并将退出状态设置为0so 更惯用的说法是我们要忽略命令的失败退出代码。大多数人会争辩说这|| true更清晰(更清楚地传达意图)。

  • `&& :` 很棒,有没有关于这个的文档或进一步阅读?谷歌没有让我试图找到这种关键字...... (7认同)

小智 9

大多数这些响应未能解决最常见的:.

首先,此讨论与任何非Bourne shell ( sh) 派生体的shell无关。也就是说,所有 Bourne 衍生外壳都将true:视为相同的东西。过去鼓励程序员使用:而不是true,因为:它总是内置的,而曾经有过true不总是内置的情况。

:有两个用途。它不是 的同义词#,但具有不同的功能。在 a 下调试脚本时set -x#使用where 的行被解析器删除并完全忽略,而 with:的行被解析和评估。这在调试中非常有用,因为在-x这些行下显示并显示评估后的值。这就像print在您的代码中放置仅在-x模式下显示的语句。小心后面的值,:因为它们是真正的代码,副作用会影响您的程序。

  • 第二个用途是什么? (3认同)

cuo*_*glm 6

通常,在 bash 中,冒号:true是等效的。

是 || : 被认为更地道?

我认为这是基于上下文的

如果你想要 a return value,或者 acondition总是 true ,你应该使用true关键字,它会让你的代码更清晰,让观众知道你想要强调true的值,即:

while true; do something
Run Code Online (Sandbox Code Playgroud)

或者

<commnad>
RETURN_VALUE= $? || true
Run Code Online (Sandbox Code Playgroud)

如果你什么都不做,或者NOP在 shell 中,你应该使用冒号:

if condition
then
    : # DO NOTHING HERE
else
    do something
fi 
Run Code Online (Sandbox Code Playgroud)

或者

while conditon
do
    : # DO NOTHING HERE
done
Run Code Online (Sandbox Code Playgroud)