理解shell内建命令

chevallier 05/10/2018. 2 answers, 105 views
bash shell shell-builtin

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 <<< 

当我在bash 4.4上运行compgen -b时,我收到了所有shell内建命令的列表。 我例如看到[kill被列为shell内建的。 但他们的实际位置是:

/usr/bin/[
/bin/kill 

我认为是一个builtin意味着该命令被编译到/bin/bash可执行文件中。 所以真正让我困惑的是:请纠正我,但是当一个单独的命令实际上不是shell的一部分时,如何将单独的命令作为builtin命令?

2 Answers


Kusalananda 05/10/2018.

内置于shell中的命令通常是内置的,因为这会提高性能。 例如,调用external printf比使用内置的printf慢。

由于一些实用程序不需要内置,除非它们是特殊的,比如cd ,它们也作为external实用程序提供。 这样一来,如果脚本被一个不提供内置等效脚本的shell解释,脚本就不会中断。

某些shell的内置插件还提供对外部等效命令的扩展。 Bash的printf ,例如能够做到

$ printf -v message 'Hello %s' "world"
$ echo "$message"
Hello world 

(打印到一个变量),因为外部/usr/bin/printf无法访问当前shell会话中的shell变量(并且不能更改它们),所以外部/usr/bin/printf根本无法执行该操作。

内置的实用程序也没有限制,即它们的扩展命令行必须小于一定的长度。 干

printf '%s\n' * 

因此printf是shell内置命令是安全的。 命令行长度的限制来自用于执行外部命令的execve() C库函数。 如果命令行和当前环境大于ARG_MAX字节(请参阅shell中的getconf ARG_MAX ),则对execve()的调用将失败。 如果该实用程序内置于shell中,则不必调用execve()

内置实用程序优先于$PATH实用程序。 要在bash禁用内置命令,请使用例如

enable -n printf 

有一个need内置到shell的实用程序清单(取自POSIX标准的特殊内置列表

break
colon (:)
continue
dot (.)
eval
exec
exit
export
readonly
return
set
shift
times
trap
unset 

这些需要内置,因为它们直接操作当前shell会话的环境和程序流。 外部工具将无法做到这一点。

有趣的是, cd不是这个列表的一部分,但POSIX对此有如下说明:

由于cd会影响当前的shell执行环境,因此它总是以常规内置的shell的形式提供。 如果在子shell或单独的实用程序执行环境中调用它,例如以下之一:

(cd /tmp)
nohup cd
find . -exec cd {} \; 

它不会影响调用者环境的工作目录。

因此,我假设“特殊”内置插件不能具有外部对应物,而理论上可以使用cd (但它不会那么做)。


terdon 05/10/2018.

你(很容易理解)被一些内建函数作为内置命令and外部命令存在的事实所困惑。 所以,虽然你是对的,例如,有一个/bin/[命令,这并不意味着它的“实际位置”在/bin

任何简单的测试方法是使用-a开关运行type ,它将显示命令的所有可用实例。 在我的Arch系统上,显示:

$ type -a [
[ is a shell builtin
[ is /sbin/[
[ is /usr/sbin/[
[ is /usr/bin/[ 

请注意, /sbin/usr/sbin/bin都是指向/usr/bin符号链接,因此只有一个外部[

$ readlink -f /usr/sbin /sbin /bin/
/usr/bin
/usr/bin
/usr/bin 

正如你所看到的, [既是内建命令又是外部命令,其他各种shell内建命令也是如此。 但是,这并没有改变它们也是shell内建的事实,它们被编译到外壳本身中。

Related questions

Hot questions

Language

Popular Tags