: 和 true 和有什么不一样?

l0b*_*0b0 16 bash dash

bash

$ type :
: is a shell builtin
$ type true
true is a shell builtin
Run Code Online (Sandbox Code Playgroud)

看起来它们是相同的,但它们没有给出相同的系统跟踪:

$ strace :
strace: :: command not found
$ strace true
execve("/bin/true", ["true"], [/* 82 vars */]) = 0
[snip]
exit_group(0)                           = ?
Run Code Online (Sandbox Code Playgroud)

我尝试比较strace bash -c : 2>:.txtand strace bash -c true 2>true.txt,但除了内存位置之外找不到它们之间的任何差异。

dash

$ type :
: is a special shell builtin
$ type true
true is a shell builtin
Run Code Online (Sandbox Code Playgroud)

好的,所以它们不一样。help :并且help true不是很有用,它们在bashand 中返回相同的值dash。除了:节省三个字节并使脚本可读性降低之外,它们之间是否有任何实际区别?

Kei*_*son 28

行为上没有真正的区别。这两个命令什么都不做,并以成功状态退出。 :强调什么都不做;true强调成功的状态。

strace true有效,因为true它既是 shell 内置命令又是外部命令 ( /bin/true);:只是一个内置的 shell(没有/bin/:- 尽管可能有,并且可能在非常旧的 Unix 系统上)。在 bash 中,尝试

type -a :
type -a true
Run Code Online (Sandbox Code Playgroud)

两者存在的原因都是历史原因。如果我没记错的话,一些非常早期的 shell 没有注释语法,所以使用 do-nothing:命令代替。

有一些内部差异dash。查看 git://git.kernel.org/pub/scm/utils/dash/dash.git 上的源代码,显示了 中的一些不同代码路径eval.c,但我无法产生任何明显不同的行为比special输出中的单词type :

  • 此外,早期版本的 UNIX 没有 `/bin/true` 或 `/bin/false`。`:` 命令有时也用于处理参数的副作用:`: ${num_times:=10}`。 (8认同)
  • `:` 是 [最初是一个标签指示器](http://unix.stackexchange.com/questions/19124/bash-multi-line-command-with-comments-after-the-continuation-character/19126#19126),回到具有 `goto` 的 Bourne shell 的祖先。显然 `:` 被滥用为评论指示器并卡住了。 (5认同)

Jod*_*e C 8

它们在 Bash 中是相同的。builtins/colon.def在 Bash-4.2 源代码中查看。

在您的命令中,strace true您实际上是在运行二进制文件/bin/true而不是 bash 内置的 true。


Kar*_*lis 6

这些命令之间的区别在于,根据定义,:它是一个特殊的内置实用程序,而true是POSIX 兼容 shell 中的常规内置实用程序。

根据 POSIX 规范特殊内置函数的处理方式略有不同:

调用特殊内置实用程序之前的变量赋值在内置实用程序完成后仍然有效;常规内置实用程序或其他实用程序不会出现这种情况。

这可以在 POSIX 兼容的 shell 中进行说明,如下所示:

$ VAR=FOO
$ VAR=BAR :
$ echo "$VAR"
BAR
Run Code Online (Sandbox Code Playgroud)
$ VAR=FOO
$ VAR=BAR true
$ echo "$VAR"
FOO
Run Code Online (Sandbox Code Playgroud)

另一个方面的区别是:

特殊内置实用程序中的错误可能会导致执行该实用程序的 shell 中止,而常规内置实用程序中的错误不应导致执行该实用程序的 shell 中止。

实际运行的示例代码:

$ ( : > ""; echo "You won't see this!" )
sh: 1: cannot create : Directory nonexistent
$  echo "Exit code: $?"
Exit code: 2
Run Code Online (Sandbox Code Playgroud)
$ ( true > ""; echo "Hello!" )
sh: 1: cannot create : Directory nonexistent
Hello!
$ echo "Exit code: $?"
Exit code: 0
Run Code Online (Sandbox Code Playgroud)