重点


  1、动手前首先要想清楚为什么实现一个 shell 要用到 fork (创建子进程),为什么不能把活全由 shell 干了呢?原因其实很简单,进程是运行的程序,一个进程就只能有一个程序(这个知识点涉及到 CS:IP 与 CPU控制权的内容),想让一个程序把其他所有程序的活都干了,显然不可能,所以 shell 相当于是一个命令解析器,把命令解析好找到对应的可执行文件后就 fork 一个子进程,将可执行文件加载入内存,运行程序,程序结束后再把结果返回给 shell,关闭进程,在父进程中显示结果,同时维持可输入状态,不能因为输入一条指令后 shell 程序就终止运行了。

  2、理解如何实现一个管道命令。管道命令的每一条cmd都有stdin、stdinout,写入第一条命令时你需要一个子进程,读出第一条cmd的stdout并作为第二条cmd的stdin时你又需要一个进程,所以这里需要再fork一次。所以在shell中实现一个管道命令,你需要用两次fork(),第一次fork中,父进程去跑shell,子进程跑管道命令的左边那条命令;第二次fork中,父进程(前一次fork中的子进程)去跑左边的命令,子进程(相当于前一次fork中父进程的孙子进程)去跑右边的命令。

  

坑点


  exec函数族的参数很坑,因为它要形如main函数的参数argv,argv是一个char **数组(即可当作是一维的字符串数组)且最后一位是NULL,注意argv最后一位必须是NULL,也就是说你传入的参数也要是一个末尾是NULL的字符串数组。这个细节编译器不会报语法错误,但是执行到这一步的时候就会出现各种报错、core dump。

 

代码


  已放在github上,地址:https://github.com/bw98/git_repo/tree/master/myshell

最新文章

  1. BZOJ4293: [PA2015]Siano
  2. IE8下ajax请求失败的解决方案
  3. Spring - 初始化spring容器
  4. IE的浏览器模式和文档模式
  5. Shibboleth
  6. telnet发电子邮件
  7. css div11
  8. donet体系结构
  9. 在sqlserver2005/2008中备份数据库,收缩日志文件
  10. Robot Framework学习笔记(三)------常用关键字介绍
  11. UOJ#104. 【APIO2014】Split the sequence 动态规划 斜率优化
  12. Centos 7安装python3(PY3.6)
  13. C#接口的显隐实现
  14. php 匹配替换中文
  15. MySQL表类型和存储引擎
  16. poj3368 Frequent values(线段树)
  17. MyBatis 实用篇(一)入门
  18. JavaScript设计模式之设计原则
  19. python中Excel表操作
  20. tp5 select回显

热门文章

  1. JAVA面试之集合框架(三)
  2. jq 时间计算
  3. Java注解Annotation详解
  4. 分水岭 golang入坑系列
  5. put()
  6. js 事件冒泡和事件捕获
  7. Java中的比较总结
  8. C#判断ListBox是否显示了水平滚动条/横向滚动条
  9. 基于AOE网的关键路径的求解
  10. 1.python的安装