从历史上看,Bourne shell 没有true
和false
作为内置命令。true
取而代之的是简单地别名为:
, 和false
类似的东西let 0
。
:
比true
对古代 Bourne 衍生贝壳的可移植性略好。作为一个简单的例子,考虑既没有!
管道运算符也没有||
列表运算符(就像一些古老的 Bourne shell 的情况)。这使得语句的else
子句if
成为基于退出状态进行分支的唯一方法:
if command; then :; else ...; fi
由于if
需要一个非空then
子句并且注释不计为非空,:
因此用作无操作。
如今(即:在现代语境中)您通常可以使用:
或true
。两者都是由 POSIX 指定的,有些true
更容易阅读。但是有一个有趣的区别::
是所谓的 POSIX special built-in,而true
是常规 built-in。
需要在 shell 中内置特殊的内置函数;常规内置仅“通常”内置,但并不能严格保证。大多数系统的 PATH 中通常不应该有一个以:
函数命名的常规程序。true
可能最关键的区别在于,对于特殊的内置插件,内置插件设置的任何变量 - 即使在简单命令评估期间的环境中 - 在命令完成后仍然存在,如使用 ksh93 所示:
$ unset x; ( x=hi :; echo "$x" )
hi
$ ( x=hi true; echo "$x" )
$
请注意,Zsh 忽略了这一要求,GNU Bash 也忽略了这一要求,除非在 POSIX 兼容模式下运行,但所有其他主要的“POSIX sh 派生”shell 都遵守这一要求,包括 dash、ksh93 和 mksh。
另一个区别是常规内置插件必须兼容exec
- 此处使用 Bash 演示:
$ ( exec : )
-bash: exec: :: not found
$ ( exec true )
$
POSIX 还明确指出:
可能比 更快true
,尽管这当然是特定于实现的细节。