为什么 cd 不是一个程序?

为什么 cd 不是一个程序?

我一直想知道为什么cd不是一个程序,但从未找到答案。

有谁知道为什么会这样?

答案1

cd命令修改了“当前工作目录”,对吗?

“当前工作目录”是每个进程唯一的属性。

所以,如果cd是一个程序,它会像这样工作:

  1. cd foo
  2. cd过程开始
  3. cd过程更改目录对于裁谈会进程
  4. 进程cd退出
  5. 您的 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拼写)是一个外部程序。它在首次实现后就意外停止工作。chdirfork

引用丹尼斯·里奇:

正当我们欢呼雀跃时,我们发现 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),实现通过单独的实用程序不可能或不方便获得的功能。例如,cdbreakcontinueexec) 无法在 shell 外部实现,因为它们直接操作 shell 本身。historygetoptskill或内置命令pwd等可以在单独的实用程序中实现,但它们作为内置命令使用更方便。所有 shell 内置函数将在后续部分中进行描述。

答案4

shell 中的命令cd不能是单独的进程,因为在 Unix 中没有机制可以更改不同进程(甚至父进程)的当前工作目录。

如果cd是一个不同的进程,那么它必须更改其父进程(shell)的当前工作目录,这在 Unix 中是不可能的。相反,cd是一个特殊的内置命令。 shell 调用诸如chdir()和 之类的函数fchdir() 来更改其当前工作目录。

注意:内核存储每个进程当前工作目录的索引节点号。子进程cwd从其父进程继承它。

相关内容