我一直想知道为什么cd
不是一个程序,但从未找到答案。
有谁知道为什么会这样?
答案1
该cd
命令修改了“当前工作目录”,对吗?
“当前工作目录”是每个进程唯一的属性。
所以,如果cd
是一个程序,它会像这样工作:
cd foo
- 该
cd
过程开始 - 该
cd
过程更改目录对于裁谈会进程 - 进程
cd
退出 - 您的 shell 仍具有与开始之前相同的状态,包括当前工作目录。
答案2
cd
除了是一个内置的 shell 之外,其实也是一个程序在 POSIX 兼容操作系统上。他们必须为常规实用程序提供独立的可执行文件,例如cd
.例如,这种情况是索拉里斯,艾克斯、HP-UX 和操作系统。
显然,内置函数cd
仍然是强制性的,因为它的外部实现不会更改当前的 shell 目录。然而,后者仍然有用。下面的示例显示了 POSIX 如何设想如何cd
使用该命令:
find . -type d -exec cd {} \;
在 POSIX 系统上,此 oneliner 将为您不允许cd
进入的所有目录报告一条错误消息。在大多数 Gnu/Linux 发行版上,它会失败并显示该错误消息:
find: `cd': No such file or directory
这是你问题的答案,“为什么 cd 不是一个程序?” 由原始 Unix 合著者之一提出。在非常早期的 Unix 实现中, (当时的cd
拼写)是一个外部程序。它在首次实现后就意外停止工作。chdir
fork
引用丹尼斯·里奇:
正当我们欢呼雀跃时,我们发现 chdir(更改当前目录)命令已停止工作。我们阅读了大量代码,并焦虑地反思添加 fork 是如何破坏 chdir 调用的。最终真相大白:在旧系统中 chdir 是一个普通命令;而在旧系统中,chdir 是一个普通命令。它调整了附加到终端的(唯一)进程的当前目录。在新系统下,chdir 命令正确地更改了为执行它而创建的进程的当前目录,但该进程立即终止,并且对其父 shell 没有任何影响!有必要使 chdir 成为一个特殊命令,在 shell 内部执行。事实证明,几个类似命令的函数具有相同的属性,例如登录。
来源:丹尼斯·M·里奇,“Unix分时系统的演变”,AT&T 贝尔实验室技术杂志 63(6),第 2 部分,1984 年 10 月,第 1577-93 页
Unix 版本 1(1971 年 3 月)chdir手册页状态:
因为每个命令都会创建一个新的进程来执行,所以如果将 chdir 写成普通命令,那么 chdir 是无效的。因此它被 Shell 识别并执行。
答案3
来自 Bash 的介绍(什么是贝壳?):
Shell 还提供一小组内置命令 (builtins),实现通过单独的实用程序不可能或不方便获得的功能。例如,
cd
、break
、continue
和exec
) 无法在 shell 外部实现,因为它们直接操作 shell 本身。history
、getopts
、kill
或内置命令pwd
等可以在单独的实用程序中实现,但它们作为内置命令使用更方便。所有 shell 内置函数将在后续部分中进行描述。
答案4
shell 中的命令cd
不能是单独的进程,因为在 Unix 中没有机制可以更改不同进程(甚至父进程)的当前工作目录。
如果cd
是一个不同的进程,那么它必须更改其父进程(shell)的当前工作目录,这在 Unix 中是不可能的。相反,cd
是一个特殊的内置命令。 shell 调用诸如chdir()
和 之类的函数fchdir()
来更改其当前工作目录。
注意:内核存储每个进程当前工作目录的索引节点号。子进程cwd
从其父进程继承它。