引出shell
从这张图我们可以看出,每当我们敲下一条指令就会相应解释并且执行此指令,但是没有敲指令的时候他总是处于等待状态中。
这就类比一个死循环,一直等待指令的输入,输入指令后,创建子进程并且将子进程替换成命令,执行子进程的同时父进程要一直等待子进程的执行结束,从而实现交互。
程序实现shell
思路:
1、获取命令行
2、解析命令行
3、创建进程,让子进程进行程序替换
4、子进程执行的时候父进程要一直等待。
原理:
具体实现的代码:
1 #include<unistd.h>
2 #include<sys/wait.h>
3 #include<stdio.h>
4 #include<stdlib.h>
5 #include<string.h>
6
7 int argc=0;
8 char* argv[8];
9 void do_parse(char* buf){//此函数的作用是解析命令
10 argc=0;
11 int i=0;
12 int flag=0;
13 for(;buf[i];i++){
//如果指令行里面还没有遇到空格,而且是参数开始状态(flag=0),就将参数存入argv中,读完之后,将状态改成参数结束(flag=1);如果遍历遇到空格借用'\0'替换掉。
14 if(!isspace(buf[i])&&flag==0){
15 argv[argc++]=buf+i;
16 flag=1;
17 }
18 else if(isspace(buf[i])){
19 buf[i]='\0';
20 flag=0;
21 }
22 }
23 }
24 void do_exec(){
//此函数的作用是创建子进程并完成程序替换,让子进程执行所解析的argv中的命令,父进程这一期间只能等待子进程退出。
25 pid_t pid=fork();
26 if(pid<0){
27 perror("fork()");
28 }
29 else if(pid>0){
30 //father
31 wait(NULL);
32 }
33 else{
34 //tihuan
35 int ret=execvp(argv[0],argv);//判断程序是否替换成功,如果成功就不会执行下面的语句。
36 if(ret==-1){
37 perror("exec");
38 exit(1);
39 }
40 }
41 }
42 int main(){
43 char buf[1024]={};
44 while(1){
45 printf("myshell>");
46 scanf("%[^\n]%*c",buf);
47 do_parse(buf);
48 do_exec();
49 }
50 }