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


36

我并没有做太多的shell脚本编写工作,因此在阅读文档git submodule时我感到有些惊讶并且看到了它们在本文档中使用的语法:

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

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


值得注意的是||:(没有空格)在bash中也有效。它执行与|| :或相同的操作|| true
布鲁诺·布罗诺斯基

Answers:


38

true没有内置在Bourne外壳中。:一直都是(这是在#介绍之前输入评论的方法)。

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

请注意POSIX Shell中的另一个区别(对于bash,仅在POSIX模式下):虽然true是常规的内置文件(甚至不必内置),但是:特殊的内置文件。这具有一些含义,其中大多数都不太可能在此特定情况下产生任何影响:

  • 如果:命令失败(包括由于重定向失败),则会导致外壳退出。在实践中,除非您将重定向传递给:

    $ sh -c ': > /   ; echo HERE'
    sh: 1: cannot create /: Is a directory
    $ sh -c 'true > /; echo HERE'
    sh: 1: cannot create /: Is a directory
    HERE
    
  • 中的var=value :,在返回后var仍设置为,而不是在以下情况下:value:true

    $ var=1; var=2 :   ; echo "$var"
    2
    $ var=1; var=2 true; echo "$var"
    1
    

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

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

set -e
false

将导致外壳程序退出,set -e并且false退出状态为非零(失败)。该set -e效果被取消如果返回一个非0状态被用作命令条件等在:

if false; then ...
while false; do ...
false && : ...
false || : ...

false && :仅取消set -efalse || :取消set -e并将退出状态设置为,0因此更习惯地说我们要忽略该命令的失败退出代码。大多数人认为这|| true更容易理解(更清楚地传达了意图)。


5
&& :非常出色,对此有任何文档或进一步的阅读吗?Google没能找到这样的关键词……
Ian Bytchek 2015年

5

通常,在bash中,冒号:true等价。

是|| :被认为更惯用吗?

我认为这是基于上下文的

如果您希望a return value或a condition始终为true,则应使用true关键字,它将使您的代码更清晰,并让查看者知道您想要强调true值,即:

while true; do something

要么

<commnad>
RETURN_VALUE= $? || true

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

if condition
then
    : # DO NOTHING HERE
else
    do something
fi 

要么

while conditon
do
    : # DO NOTHING HERE
done

5

这些响应大多数都无法解决的最常见用法:

首先,该讨论与不是Bourne shellsh)派生词的任何shell不相关。这就是说,所有的Bourne衍生炮弹看到true:为同样的事情。过去鼓励程序员使用:而不是true,因为:它始终是内置的,而在某些情况下true并非总是内置的。

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


1
第二用途是什么?
Peter Mortensen
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.