免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 6807 | 回复: 3

[FreeBSD] 由cd命令的简单实现来看shell内部命令和外部命令 [复制链接]

论坛徽章:
0
发表于 2014-06-25 01:27 |显示全部楼层
本帖最后由 fender0107401 于 2014-06-25 08:50 编辑

首先shell就是一个进程。

cd命令用来切换当前的工作目录,这个命令是shell内置的,这表示shell在执行cd命令的时候,并不需要创建一个子进程去执行cd命令,而是在其内部解析并执行的。

cd命令可以用下面简单的几行代码来实现,这里只为说明问题的本质:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>

  4. int main(int argc,char *argv[])
  5. {
  6.    int chdir_return;
  7.    char cwd_buf[300];
  8.    
  9.    if(argc < 2)
  10.     {
  11.        printf("error1\n");
  12.        exit(0);
  13.     }

  14.    printf("before call chdir fuction-current directory is %s\n",getwd(cwd_buf));

  15.    chdir_return = chdir(argv[1]);
  16.    if(chdir_return < 0)
  17.       {
  18.         printf("error2\n");
  19.         exit(1);
  20.       }
  21.   
  22.    printf("after call chdir fuction-current directory is %s\n",getwd(cwd_buf));

  23.    return 0;
  24. }
复制代码
编译并执行后如下所示:
  1. root@:/home/jianjunv5 # gcc -o test_cd test_cd.c
  2. root@:/home/jianjunv5 # ./test_cd /usr/src
  3. before call chdir fuction-current directory is /home/jianjunv5
  4. after call chdir fuction-current directory is /usr/src
  5. root@:/home/jianjunv5 # pwd
  6. /home/jianjunv5
  7. root@:/home/jianjunv5 # cd /usr/src/
  8. root@:/usr/src # pwd
  9. /usr/src
复制代码
从上面的结果说明了三个问题:
1:test_cd是一个外部命令,shell创建一个子进程去执行这个cmd。
2:子进程执行chdir系统调用只影响子进程的当前目录,而不会影响父进程(shell)的当前目录。
3:子进程继承父进程的当前目录这个属性

再深入一步,就更接近答案了:

进程在在freebsd内部是通过struct proc对象来描述的,该对象包含下面的一个成员,该成员用来和进程打开的文件进行交互:
  1. struct filedesc        *p_fd;                /* (b) Open files. */
复制代码
p_fd指向一个类型为struct filedesc的数据对象,该数据对象包含下面的一个成员,用来指向描述当前目录的struct vnode对象 :
  1. 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类似。

论坛徽章:
89
水瓶座
日期:2014-04-01 08:53:31天蝎座
日期:2014-04-01 08:53:53天秤座
日期:2014-04-01 08:54:02射手座
日期:2014-04-01 08:54:15子鼠
日期:2014-04-01 08:55:35辰龙
日期:2014-04-01 08:56:36未羊
日期:2014-04-01 08:56:27戌狗
日期:2014-04-01 08:56:13亥猪
日期:2014-04-01 08:56:02亥猪
日期:2014-04-08 08:38:58程序设计版块每日发帖之星
日期:2016-01-05 06:20:00程序设计版块每日发帖之星
日期:2016-01-07 06:20:00
发表于 2014-06-25 08:51 |显示全部楼层
注意使用论坛自带的格式,这样其他版友看起来方便,然后交流起来容易些。

论坛徽章:
0
发表于 2014-06-25 10:02 |显示全部楼层
回复 2# fender0107401

初来乍到 多谢版主指出 版主没有直接删帖就是最大的鼓励 后续会注意。


   

论坛徽章:
89
水瓶座
日期:2014-04-01 08:53:31天蝎座
日期:2014-04-01 08:53:53天秤座
日期:2014-04-01 08:54:02射手座
日期:2014-04-01 08:54:15子鼠
日期:2014-04-01 08:55:35辰龙
日期:2014-04-01 08:56:36未羊
日期:2014-04-01 08:56:27戌狗
日期:2014-04-01 08:56:13亥猪
日期:2014-04-01 08:56:02亥猪
日期:2014-04-08 08:38:58程序设计版块每日发帖之星
日期:2016-01-05 06:20:00程序设计版块每日发帖之星
日期:2016-01-07 06:20:00
发表于 2014-06-25 10:04 |显示全部楼层
回复 3# 71v5

相互学习。

   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP