在bash
:
$ type :
: is a shell builtin
$ type true
true is a shell builtin
看起来它们是相同的,但它们没有给出相同的系统跟踪:
$ strace :
strace: :: command not found
$ strace true
execve("/bin/true", ["true"], [/* 82 vars */]) = 0
[snip]
exit_group(0) = ?
我尝试比较strace bash -c : 2>:.txt
和strace bash -c true 2>true.txt
,但除了内存位置之外,找不到它们之间的任何差异。
在dash
:
$ type :
: is a special shell builtin
$ type true
true is a shell builtin
好吧,所以它们不一样。help :
和help true
不是很有用,它们在bash
和中返回相同的值dash
。除了:
节省三个字节并使脚本可读性较差之外,它们之间有任何实际区别吗?
答案1
行为上没有真正的区别。这两个命令都不执行任何操作并以成功状态退出。 :
强调什么都不做;true
强调成功的状态。
strace true
之所以有效,是因为true
它既是 shell 内置命令又是外部命令 ( /bin/true
);:
只是一个内置的 shell(没有/bin/:
——尽管可能有,而且可能是在非常古老的 Unix 系统上)。在bash中,尝试
type -a :
type -a true
两者存在的原因都是历史性的。如果我没记错的话,一些非常早期的 shell 没有注释语法,因此:
使用了 do-nothing 命令。
存在一些内部差异dash
。查看源代码(可在 git://git.kernel.org/pub/scm/utils/dash/dash.git 获取),显示了 中的一些不同的代码路径eval.c
,但我无法产生任何明显不同的行为比special
的输出中的单词type :
。
答案2
它们在 Bash 中是相同的。查看builtins/colon.def
Bash-4.2 源代码。
在你的命令中,strace true
你实际上运行的是二进制文件,/bin/true
而不是 bash 内置的 true。
答案3
命令之间的区别在于,根据定义:
是特殊内置效用而true
是常规内置POSIX 兼容 shell 中的实用程序。
根据 POSIX 规范,特殊内置处理方式略有不同:
调用特殊内置实用程序之前的变量赋值在内置实用程序完成后仍然有效;常规内置实用程序或其他实用程序不会出现这种情况。
这可以在 POSIX 兼容的 shell 中进行说明,如下所示:
$ VAR=FOO
$ VAR=BAR :
$ echo "$VAR"
BAR
$ VAR=FOO
$ VAR=BAR true
$ echo "$VAR"
FOO
另一个方面的区别是:
特殊内置实用程序中的错误可能会导致执行该实用程序的 shell 中止,而常规内置实用程序中的错误不应导致执行该实用程序的 shell 中止。
实际运行的示例代码:
$ ( : > ""; echo "You won't see this!" )
sh: 1: cannot create : Directory nonexistent
$ echo "Exit code: $?"
Exit code: 2
$ ( true > ""; echo "Hello!" )
sh: 1: cannot create : Directory nonexistent
Hello!
$ echo "Exit code: $?"
Exit code: 0