我一直想知道为什么cd
不是一个程序,但从未设法找到答案。
有人知道为什么会这样吗?
cd
命令是一个单独的程序。外壳专门处理它的原因是它不能fork
,只是exec
。当cd
做,它会Exec的sh
。我不知道这是不是真实的故事。
cd
一个我读过的故事。既然@jlliagre填写了详细信息,我对此方面显然是错误的。
我一直想知道为什么cd
不是一个程序,但从未设法找到答案。
有人知道为什么会这样吗?
cd
命令是一个单独的程序。外壳专门处理它的原因是它不能fork
,只是exec
。当cd
做,它会Exec的sh
。我不知道这是不是真实的故事。
cd
一个我读过的故事。既然@jlliagre填写了详细信息,我对此方面显然是错误的。
Answers:
该cd
命令修改“当前工作目录”,对吗?
“当前工作目录”是每个进程唯一的属性。
因此,如果cd
是一个程序,它将像这样工作:
cd foo
cd
过程开始cd
进程将更改cd进程的目录cd
进程退出cd
是程序,它将像这样工作”应该是“ cd
在其外部程序实现中使用时,它确实会这样工作”。
cd
除了内置的Shell外,实际上也是 POSIX兼容OS上的程序。他们必须为常规实用程序(例如)提供独立的可执行文件cd
。例如,Solaris,AIX,HP-UX和OS X就是这种情况。
显然,内建cd
函数仍然是必需的,因为其外部实现不会更改当前的shell目录。但是,后者仍然有用。这是一个示例,显示了POSIX如何设想如何使用此cd
命令:
find . -type d -exec cd {} \;
在POSIX系统上,此oneliner将报告您不允许进入的所有目录的错误消息cd
。在大多数Gnu / Linux发行版中,它失败并显示以下错误消息:
find: `cd': No such file or directory
这是原始Unix合著者之一对您的问题“ 为什么cd不是程序? ” 的答案。在一个非常早的Unix实现中,cd
(chdir
当时是拼写的)是一个外部程序。fork
首次实施后,它只是意外停止了工作。
在我们欢腾的过程中,发现chdir(更改当前目录)命令已停止工作。关于添加fork可能会破坏chdir调用的内容,有大量的代码阅读和焦虑的内省。最终,事实浮出水面:在旧系统中,chdir是一个普通命令;它调整了附加到终端的(唯一)进程的当前目录。在新系统下,chdir命令正确地更改了创建的进程的当前目录以执行该进程,但是该进程立即终止,并且对其父外壳没有任何影响!有必要使chdir成为特殊命令,该命令在shell内部执行。事实证明,几个类似命令的功能具有相同的属性,例如login。
资料来源: Dennis M. Ritchie,“ Unix分时系统的演进 ”,AT&T贝尔实验室技术期刊63(6),第2部分,1984年10月,第1577–93页
Unix版本1(1971年3月)chdir 手册页指出:
因为创建了一个新进程来执行每个命令,所以如果将chdir作为普通命令编写,它将无效。因此,它由Shell识别并执行。
cd
可执行文件,但不应执行任何操作(除非使用错误的参数调用可能会发出错误消息)。奇怪的。
/bin/cd
。如果您想采用我的代码并自行完成自己的任务,欢迎您这样做。
cd
shell中的命令不能是单独的进程,因为在Unix中,没有机制可以更改其他进程(甚至是父进程)的当前工作目录。
如果cd
进程不同,则必须更改其父级(shell)的当前工作目录,而这在Unix中是不可能的。而是cd
一个特殊的内置命令。Shell调用像chdir()
和fchdir()
更改其自身当前工作目录这样的函数。
注意:内核为每个进程存储当前工作目录的索引节点号。子进程继承cwd
自其父进程。
cd是shell内置命令。就这么简单。CD的人说了这一切。cd命令更改所有解释器和(在线程环境中)所有线程的工作目录。
cd
是内置。我建议您阅读排名最高的答案,并考虑如何改善您的答案。
我认为人们回答中缺少的一件事是当前目录是每个程序都可以更改的环境变量。如果使用“导出”命令查看当前环境变量列表,则将具有:
declare -x PWD="/home/erfan"
在您的结果中。因此,通过“ cd”命令,我们只想修改此内部变量。我认为,如果尝试,当然可以在shell中更改任何pty的PWD变量。喜欢:
cder #change current PTY $PWD variable
但是我认为在正常情况下没有必要。换句话说,我们从bash(或任何shell)获得帮助来修改其定义的内部变量。
..
路径,而不是您从其开始的路径:(#include <stdlib.h>
int main(void) { chdir(".."); puts(getenv("PWD")); }
顺便说一下,C壳将CWD公开为%cwd。)
#include <unistd.h>
int main(void) { char ac[99]; setenv("PWD", "/", 1); puts(getcwd(ac, sizeof(ac))); }
它表明:它将显示您从中启动程序的目录,而不是/
。
$PWD
仅对Bourne外壳有意义。这只是Shell与Shell脚本交流它知道的内容的一种方法,因此他们不必调用pwd
即可查找它。任何独立程序(取决于的值)$PWD
都是不可靠的。