在Linux中,什么是Shell内置命令?

17

我刚刚开始使用Linux,对于像cd这样的shell内置命令是如何定义的很感兴趣。

此外,如果有人能够解释它们是如何实现和执行的,我将不胜感激。


1
这与内核无关。 - Thomas M. DuBuisson
6个回答

16
如果您想了解bash内建命令的定义,则只需查看Bash手册的第4节
如果您想了解bash内建命令的实现方式,则需要查看Bash源代码,因为这些命令已经编译进bash可执行文件中。
要快速轻松地查看命令是否是bash内置命令,可以使用help命令。例如,help cd将显示如何定义'cd'的bash内置命令。同样适用于help echo

12

不同的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

理论上,cd实用程序没有阻止一个shell实现者将其作为外部命令来实现的。 cd不能直接更改shell的当前目录,但是例如,cd可以通过套接字向shell进程通信新目录。但是没有人这么做,因为没有意义。除了非常旧的shell(其中没有内置概念)之外,在那里,cd使用一些肮脏的系统黑客来完成其工作。

cd在shell内部是如何实现的?基本算法在这里描述。它还可以执行一些工作以支持shell的额外功能。


4

Manjari,查看来自ftp://ftp.gnu.org/gnu/bash/bash-2.05b.tar.gz的bash shell源代码。 你会发现shell内置命令的定义不在单独的二进制可执行文件中,而是在shell二进制文件本身中(名称shell内置明确表明了这一点)。


3
每个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进行fork操作,execs /bin/chmod(将"777"和"foo"作为参数传递),然后新的chmod进程运行C代码chmod("foo", 777);并返回控制权给shell。但是对于cd命令来说,这种方式行不通。即使cd看起来与chmod相同,它必须有所不同:如果shell生成另一个进程来执行chdir系统调用,则只会更改该新生成的进程的目录,而不是shell的目录。然后,当进程返回时,shell将停留在一直存在的相同目录中 - 因此cd需要作为shell内置命令实现。

1

2
不是完全正确的 - 有时内置函数和可执行文件会重叠,例如虽然存在 '/bin/echo' 程序,但大多数 Shell 提供自己的 echo 内置函数。 - el.pescado - нет войне
另一个例子是“时间”。 - Massimo Fazzolari

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接