自己动手制作一个简易的shell
来源:互联网 发布:随身带了淘宝去异界 编辑:程序博客网 时间:2024/06/05 01:17
本人最近在看《Unix环境高级编层》,其上面的程序清单1-5的程序介绍了如何制作一个shell,而后本人又做了一点改进,改进的地方如下:
1.为了方便查看,删除了原来的err_sys()函数和其自定义的"apue.h"这个头文件!
2.增加了对于命令选项处理的功能,但是不是很强大,目前只能处理单个参数!
本人写的代码如下:
#include<stdio.h>#include<string.h>#include<unistd.h>#include<sys/types.h>#include<sys/wait.h>#include<stdlib.h>#define MAXLINE 2048int main(int argc,char *argv[]){ char buf[MAXLINE]; char com[MAXLINE]; char para[MAXLINE]; int i=0,p_l=0,c_l=0; pid_t pid; //存储子进程的id int status;//waitpid函数返回的子进程的状态 printf("%%"); //输出提示符% while((fgets(buf,MAXLINE,stdin)) != NULL) {if(buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1]='\0';//重新设置命令和参数i=0;p_l=0;memset(com,0,MAXLINE);c_l=0;memset(para,0,MAXLINE); printf("buf:%s\n",buf);while(buf[i] == ' ')//将命令开始的空格都给忽略掉 i++;while(buf[i] != ' ')//读取命令{ com[c_l]=buf[i]; i++; c_l++;}while(buf[i] == ' ')//将命令和参数之间的空格都给忽略掉 i++;while(buf[i] != '\0')//读取参数{ if(buf[i] != ' ') //将参数中间的空格忽略掉 { para[p_l]=buf[i]; p_l++; } i++;} printf("com:%s para:%s\n",com,para); pid=fork();//创建子进程if(pid < 0)//创建子进程出错{ perror("fork error");}else if(pid == 0)//子进程的执行部分{ if(para[0] != 0)execlp(com,com,para,(char *)0); execlp(com,com,(char *)0); perror("execlp error"); //如果execlp()函数无法执行,则输出错误信息! exit(127);}if((pid = waitpid(pid,&status,0)) < 0)//父进程等待子进程结束{ perror("waitpid error");}memset(buf,0,MAXLINE);//重新设置buf的缓存空间printf("%%"); } return 0;}
这个程序的思路是这样的,
数据部分,我创建了三个char数组,buf,com,para,分别用来存储读取到的字符串,分析到的命令,分析到的参数!三个int型变量,i,p_l,c_l。分别用来给buf、para、com计数!
执行部分,首先通过fgets()函数将命令读取到buf这个char数组中。然后将com和para数组全部初始化为0。然后,就开始分析命令。
分析过程如下:
首先,将命令开始的空格全部忽略。第二,从第一个非空格部分到下一个空格为命令部分,存储到com数组中!第三,读取完命令之后,剩下的部分全部视为参数了,并且忽略掉其中的空格,存储到para数组中!
Ok,这样,分析就分析完了,开始执行!这里的思路主要就是当前这个进程创建一个子进程,然后将上面分析到的命令和参数传递给execlp()函数,让子进程执行execlp()函数,execlp函数的主要功能是将其传入的命令替换掉进程中的程序部分,这样子进程执行的就是我们给execlp()函数传递命令和参数了!
这里,我想讲一下个人对于fork()这个函数的理解,如若有误,还请多多指出!
如上图所示,个人认为fork函数是一个分水岭,在这里开始创建一个子进程,子进程复制了父进程的数据和程序,这时就有两个进程在执行中间这段代码了,fork()函数给父进程返回的是子进程的pid(正常情况下,如果出错,返回一个小于0的值),给子进程返回的pid是0。所以父进程什么也没执行,直接执行到了waitpid()那里,而子进程呢,由于其pid是0,所以执行了if(pid==0)这个条件下的代码!
在if(pid == 0)中,子进程执行了execlp()函数,这个函数就是将进程中的代码全部替换成其传入命令的代码,比如,如果我们给execlp传入的是ls命令,那么这个子进程执行的完全就是ls命令的代码。
通过这样,我们就成功的实现了一个极其简单的shell!以下是结果的截图:
当然,问题还是很多的,比如执行cd ..就不行,输出变量也不行!
最后,俺想说一句,俺能力有限,水平有限,做出这个程序实在是为了自娱自乐,有很多不足的地方,还请各位大神轻拍啊!
- 自己动手制作一个简易的shell
- 一个简易的shell
- 自己动手写一个简单的Shell之一:了解Shell
- 制作一个简易的相册用js
- 制作一个简易的PHP框架
- 自己动手写一个简单的Shell之二:运行程序
- 自己动手写一个简单的Shell之三:命令行解析
- 自己动手写一个简单的Shell之四:流程控制
- 自己动手写一个简单的Windows shell扩展程序
- 用MFC的对话框制作一个简易的图片浏览器
- 关于一个简易的Html5音乐播放器的制作
- 我制作的一个简易五子棋,不懂来问…
- Android笔记(十九)制作一个简易的指南针
- 网页制作:一个简易美观的登录界面
- 自己动手开发简易的Web服务器
- 简易的shell ---- MOS 的一个小练习题
- 简易聊天室的制作
- 制作简易的计算器
- 南阳理工91——阶乘之和
- 不习惯的生活
- HDU 2084 数塔
- Android进程的内存管理分析
- Android 4.1 Audio系统变化说明
- 自己动手制作一个简易的shell
- Linux文件系统管理命令(第二版)
- Android内存泄漏分析及调试
- mysql 存储过程学习总结
- Android Out Of Memory(OOM) 的详细研究
- 网络编程中的注意问题
- ubuntu "无法获得锁"
- 数据结构之树状数组
- 内存管理