在bash 手册中,它写道
Builtin commands are contained >>> within <<< the shell itself
此外,这个答案指出
A built-in command is simply a command that the shell carries out itself,
instead of interpreting it as a request to load and run some
>>> other program <<<
当我运行compgen -b
时bash 4.4
,我会收到所有 shell 内置命令的列表。例如,我看到[
并被kill
列为 shell 内置函数。但他们的实际位置是:
/usr/bin/[
/bin/kill
我认为这builtin
意味着命令被编译成/bin/bash
可执行文件。那么真正让我困惑的是:请纠正我,但是一个单独的命令怎么可能是 a builtin
,当它实际上不是 shell 的一部分时呢?
内置在 shell 中的命令通常是内置的,因为这可以提高性能。例如,调用external
printf
比使用 built-in 慢printf
。由于某些实用程序不需要内置,除非它们是特殊的,例如
cd
,它们也作为外部实用程序提供。这样一来,如果脚本由不提供内置等效项的 shell 解释,它们就不会中断。一些 shell 的内置函数还提供了对外部等效命令的扩展。Bash 的
printf
,例如能够做到(打印到变量)外部
/usr/bin/printf
根本无法做到这一点,因为它无法访问当前 shell 会话中的 shell 变量(并且无法更改它们)。内置实用程序也没有限制,即它们的扩展命令行必须短于某个长度。正在做
因此如果
printf
是一个 shell 内置命令是安全的。命令行长度的限制来自execve()
用于执行外部命令的 C 库函数。如果命令行和当前环境大于ARG_MAX
字节(参见getconf ARG_MAX
shell),调用execve()
将失败。如果该实用程序内置在 shell 中,execve()
则不必调用。内置实用程序优先于
$PATH
. 要禁用 中的内置命令bash
,请使用例如有一个需要内置到 shell 中的实用程序的简短列表(取自 POSIX 标准的特殊内置列表)
这些需要内置,因为它们直接操纵当前 shell 会话的环境和程序流。外部实用程序将无法做到这一点。
有趣的是,
cd
它不在此列表中,但 POSIX 对此做了以下说明:因此,我假设“特殊”内置程序不能有外部对应项,而
cd
理论上可以有(但它不会做太多)。您(非常可以理解)对某些内置命令既作为内置命令又作为外部命令存在这一事实感到困惑。所以,虽然你是对的,例如,有一个
/bin/[
命令,但这并不意味着它的“实际位置”在/bin
.任何简单的测试方法都是使用将显示命令的所有可用实例
type
的开关运行。-a
在我的 Arch 系统上,显示:请注意
/sbin
,/usr/sbin
和/bin
都是指向 的符号链接/usr/bin
,因此只有一个外部[
:如您所见,
[
既是内置命令又是外部命令,其他各种 shell 内置命令也是如此。但是,这并没有改变它们也是 shell 内置函数,编译到 shell 本身的事实。