- 论坛徽章:
- 0
|
本帖最后由 fender0107401 于 2014-06-25 08:50 编辑
首先shell就是一个进程。
cd命令用来切换当前的工作目录,这个命令是shell内置的,这表示shell在执行cd命令的时候,并不需要创建一个子进程去执行cd命令,而是在其内部解析并执行的。
cd命令可以用下面简单的几行代码来实现,这里只为说明问题的本质:- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- int main(int argc,char *argv[])
- {
- int chdir_return;
- char cwd_buf[300];
-
- if(argc < 2)
- {
- printf("error1\n");
- exit(0);
- }
- printf("before call chdir fuction-current directory is %s\n",getwd(cwd_buf));
- chdir_return = chdir(argv[1]);
- if(chdir_return < 0)
- {
- printf("error2\n");
- exit(1);
- }
-
- printf("after call chdir fuction-current directory is %s\n",getwd(cwd_buf));
-
- return 0;
- }
复制代码 编译并执行后如下所示:- root@:/home/jianjunv5 # gcc -o test_cd test_cd.c
- root@:/home/jianjunv5 # ./test_cd /usr/src
- before call chdir fuction-current directory is /home/jianjunv5
- after call chdir fuction-current directory is /usr/src
- root@:/home/jianjunv5 # pwd
- /home/jianjunv5
- root@:/home/jianjunv5 # cd /usr/src/
- root@:/usr/src # pwd
- /usr/src
复制代码 从上面的结果说明了三个问题:
1:test_cd是一个外部命令,shell创建一个子进程去执行这个cmd。
2:子进程执行chdir系统调用只影响子进程的当前目录,而不会影响父进程(shell)的当前目录。
3:子进程继承父进程的当前目录这个属性
再深入一步,就更接近答案了:
进程在在freebsd内部是通过struct proc对象来描述的,该对象包含下面的一个成员,该成员用来和进程打开的文件进行交互:- struct filedesc *p_fd; /* (b) Open files. */
复制代码 p_fd指向一个类型为struct filedesc的数据对象,该数据对象包含下面的一个成员,用来指向描述当前目录的struct vnode对象 :- struct vnode *fd_cdir; /* current directory */
复制代码 某些属性是属于进程的,比如"当前目录"这个属性就属于进程,在shell创建一个子进程来执行外部命令的时候,子进程的大部分
属性从父进程(shell)继承而来,其中就包括"当前目录"这个属性,即子进程和父进程的fd_cdir指向同一个struct vnode对象,
子进程没有执行chdir系统调用之前,子进程和父进程的当前目录相同,从上面的打印结果可以看出来;当子进程执行chdir
系统调用后,子进程的当前目录被修改,即子进程 fd_cdir成员指向了描述"/usr/src"的struct vnode对象,而父进程没有
改变,从上面的打印结果也可以直接看出来。
所以,cd属于shell的内置命令,即shell不创建一个子进程来执行cd,而是由其自身解释,并在其内部执行chdir系统调用,
这样才会修改shell自身的一些属性。
其它内部命令和cd类似。 |
|