一尘不染

:(colon) GNU Bash 内置的目的是什么?

javascript

一个什么都不做的命令的目的是什么,只是一个评论领导者,但实际上是一个内置的 shell 本身?

它比每次调用向脚本中插入评论要慢约 40%,这可能因评论的大小而有很大差异。我能看到的唯一可能的原因是:

# poor man's delay function
for ((x=0;x<100000;++x)) ; do : ; done

# inserting comments into string of commands
command ; command ; : we need a comment in here for some reason ; command

# an alias for `true'
while : ; do command ; done

我想我真正在寻找的是它可能具有的历史应用。


阅读 80

收藏
2022-07-16

共1个答案

一尘不染

从历史上看,Bourne shell 没有truefalse作为内置命令。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 所示:

```bash
$ unset x; ( x=hi :; echo “$x” )
hi
$ ( x=hi true; echo “$x” )

$
```

请注意,Zsh 忽略了这一要求,GNU Bash 也忽略了这一要求,除非在 POSIX 兼容模式下运行,但所有其他主要的“POSIX sh 派生”shell 都遵守这一要求,包括 dash、ksh93 和 mksh。

  • 另一个区别是常规内置插件必须兼容exec- 此处使用 Bash 演示:

bash $ ( exec : ) -bash: exec: :: not found $ ( exec true ) $

  • POSIX 还明确指出:可能比 更快true,尽管这当然是特定于实现的细节。
2022-07-16