在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>:.txt
and 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
不是很有用,它们在bash
and 中返回相同的值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 :
。
它们在 Bash 中是相同的。builtins/colon.def
在 Bash-4.2 源代码中查看。
在您的命令中,strace true
您实际上是在运行二进制文件/bin/true
而不是 bash 内置的 true。
这些命令之间的区别在于,根据定义,:
它是一个特殊的内置实用程序,而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)