【发布时间】:2010-07-07 06:23:17
【问题描述】:
刚开始使用Linux,很好奇cd等shell内置命令是如何定义的。
另外,如果有人能解释它们是如何实现和执行的,我将不胜感激。
【问题讨论】:
-
这和内核无关。
刚开始使用Linux,很好奇cd等shell内置命令是如何定义的。
另外,如果有人能解释它们是如何实现和执行的,我将不胜感激。
【问题讨论】:
如果您想了解 bash 内置函数是如何定义的,那么您只需查看 Section 4 of The Bash Man Page。
但是,如果您想知道 bash bultins 是如何实现的,则需要查看 the Bash source code,因为这些命令已编译到 bash 可执行文件中。
查看命令是否为 bash 内置命令的一种快速简便的方法是使用 help 命令。例如,help cd 将向您展示 'cd' 的 bash 内置函数是如何定义的。 help echo 也是如此。
【讨论】:
实际的内置函数集因 shell 而异。有:
您可以使用type 命令查看该实用程序是否内置,大多数shell 都支持该命令(尽管它的输出不是标准化的)。来自dash的例子:
$ type ls
ls is /bin/ls
$ type cd
cd is a shell builtin
$ type exit
exit is a special shell builtin
Re cd 实用程序,理论上没有什么能阻止 shell 实现者将其作为外部命令实现。 cd 不能直接更改 shell 的当前目录,但是,例如,cd 可以通过套接字将新目录传递给 shell 进程。但是没有人这样做,因为没有意义。除了非常古老的 shell(没有内置的概念),cd 使用了一些肮脏的系统黑客来完成它的工作。
cd 在 shell 中是如何实现的?基本算法描述为here。它还可以做一些工作来支持 shell 的额外功能。
【讨论】:
曼贾里, 从ftp://ftp.gnu.org/gnu/bash/bash-2.05b.tar.gz查看bash shell的源代码 您会发现 shell 内置命令的定义不是在单独的二进制可执行文件中,而是在 shell 二进制文件本身中(shell built-in 的名称清楚地表明了这一点)。
【讨论】:
每个 Unix shell 至少有一些内置命令。这些内置命令是 shell 的一部分,并作为 shell 源代码的一部分实现。 shell 识别出它被要求执行的命令是它的内置命令之一,它自己执行该操作,而不调用单独的可执行文件。不同的 shell 有不同的内置函数,但在基本集合中会有很多重叠。
有时,出于性能原因,内置函数是内置的。在这种情况下,$PATH 中通常还有该命令的一个版本(可能具有不同的功能集、不同的可识别命令行参数集等),但 shell 决定将该命令也实现为内置命令,以便它可以省去产生一个短期进程的工作来做一些它可以自己做的工作。 bash 和 printf 就是这种情况,例如:
$ type printf
printf is a shell builtin
$ which printf
/usr/bin/printf
$ printf
printf: usage: printf [-v var] format [arguments]
$ /usr/bin/printf
/usr/bin/printf: missing operand
Try `/usr/bin/printf --help' for more information.
请注意,在上面的示例中,printf 既是一个内置的 shell(作为 bash 本身的一部分实现),也是一个外部命令(位于 /usr/bin/printf)。请注意,它们的行为也不同 - 当不带参数调用时,内置版本和命令版本会打印不同的错误消息。另请注意-v var 选项(将此 printf 的结果存储到名为 var 的 shell 变量中)只能作为 shell 的一部分完成 - 像 /usr/bin/printf 这样的子进程无法访问 shell 的变量执行了他们。
这将我们带到故事的第二部分:一些命令是内置的,因为它们需要。一些命令,如chmod,是系统调用的薄包装。当您运行/bin/chmod 777 foo 时,shell 分叉,执行 /bin/chmod(传递“777”和“foo”)作为参数,新的 chmod 进程运行 C 代码 chmod("foo", 777);,然后将控制权返回给 shell。不过,这不适用于cd 命令。尽管cd 看起来与chmod 的情况相同,但它的行为必须有所不同:如果shell 生成了另一个进程来执行chdir 系统调用,它只会更改那个新生成的进程的目录,而不是壳。然后,当进程返回时,shell 将保留在与一直相同的目录中 - 因此 cd 需要作为 shell 内置实现。
【讨论】:
Shell 内置 -- http://linux.about.com/library/cmd/blcmdl1_builtin.htm 例如。 -
which cd
/usr/bin/which: no cd in (/usr/bin:/usr/local/bin......
不是内置的 shell,而是二进制文件。
which ls
/bin/ls
【讨论】:
echo 内置。
【讨论】: