在学习了进程等待和程序替换及其相关函数之后,就可以实现一个我们自己简单mini_shell了。
shell及其运行原理:
https://blog.csdn.net/Miss_Monster/article/details/86370076
shell工作的基本过程
1.读取用户由键盘输入的命令行。
2.分析命令,以命令名作为文件名,并将其它参数改造为系统调用execve( )内部处理所要求的形式。
3.终端进程调用fork( )建立一个子进程。
4.终端进程本身调用wait4()来等待子进程完成(如果是后台命令,则不等待)。当子进程运行时调用execve(),子进程根据文件名到目录中查找有关文件,调入内存,执行这个程序。
5.如果命令末尾有&,则终端进程不用执行系统调用wait4(),立即发提示符,让用户输入下一条命令;否则终端进程会一直等待,当子进程完成工作后,向父进程报告,此时中断进程醒来,作必要的判别工作后,终端发出命令提示符,重复上述处理过程。
知道了基本工作原理过程,我们来实现一个简易的shell。
为了与原本系统的命令行提示符进行区分,我们把原来的 [admin@localhost mini_shell]$ 改为我们自己的[ZH@localhost zh]# 下面是具体代码实现及代码解释:
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #define MAX 1024
5 #define NUM 32
6 int main()
7 {
8 char* myargv[NUM];//字符串拆分后,一个个放进NUM
9 char cmd[MAX];//设置缓冲区大小
10
11 for(;;)
12 {
13 printf("[ZH@localhost zh]# ");//printf不加\n,表示消息不回立即显示,会被放进缓冲区
14 fflush(stdout); //刷新缓冲区,输出printf的内容
15 fgets(cmd,MAX,stdin);//从标准输入中读取一行
16 cmd[strlen(cmd)-1]=0; //将\n改为0,取消多余的空行
17 //ls -a -b -c -d
18 int i = 0;
19 myargv[i]=strtok(cmd," ");
20 i++;
21 while(1) //循环执行
22 {
23 char* p=strtok(NULL," ");//字符串拆分函数
24 if(p==NULL)//后面没有子串,则退出
25 {
26 myargv[i]=NULL;
27 break;
28 }
29 myargv[i]=p;//调用字符串拆分函数
30 i++;
31 }//到此命令行参数解释完毕
32 pid_t id =fork();//fork建立子进程可以使mini_shell一直运行
33 if(id<0)
34 {
35
36 }else if(id==0)
37 {//child
38 execvp(myargv[0],myargv);/调用替换函数将程序和执行命令替换
39 }else{
40 waitpid(id,NULL,0);//父进程等待子进程执行完毕
41 }
42 }
43 // for(i=0;myargv[i]!=NULL;i++)
44 //{
45 // printf("%d:%s\n",i,myargv[i]);
46 // }
47 return 0;
48 }
进行一下功能检验:
一些简单的基本命令都可以完成!