目录
shell是命令行解释器,功能就是捕捉用户的输入,然后根据输入的信息运行指定的命令程序。
(1)捕捉用户输入
(2)字符串解析,得到命令名称和运行参数
(3)创建子进程,并对子进程进行程序替换,设置运行参数
(4)进程等待,防止子进程成为僵尸进程
(5)循环上述操作
(1)捕捉用户输入
通过fgets函数读取用户输入保存到input字符数组中。
注意:用户输入可能夹带空格,不能使用scanf函数进行输入捕捉。
(2)字符串解析,得到命令名称和运行参数
通过指针数组argv保存每一个操作或选项的字符首地址,并将每个操作或选项的末尾的下一个字符替换为'\0'。
注意:argv末尾位置需要替换为NULL,以空作为参数结尾
(3)创建子进程,并对子进程进行程序替换,设置运行参数
通过pid对父子进程进行分流,利用execvp函数对子进程进行程序替换,让子进程运行对应的指令程序。
注意:不能直接对minishell进行替换,因为替换后运行完新程序,进程就会退出;并且如果替换了minishell,在运行某个指令程序时崩溃,minishell也就崩溃了。因此需要创建子进程,通过子进程来运行指令程序。
(4)进程等待,防止子进程成为僵尸进程
通过wait方法,让父进程等待子进程运行完毕退出,防止子进程成为僵尸进程。
(5)循环上述操作
利用while循环进行上述操作。
- #include<stdio.h>
- #include<unistd.h>
- #include<string.h>
- #include<stdlib.h>
- #include<sys/wait.h>
-
- int main(){
- extern char** environ;//声明环境变量
- while(1){
- //1.捕捉用户输入
- printf("[username&hostname]$ ");
- fflush(stdout);//刷新缓冲区
- char input[1024]={0};
- fgets(input,1023,stdin);//从标准输入读取一行数据,数据不能大于1023字节
- input[strlen(input)-1]='\0';//将最后一个字符换为\0
-
- //2.字符串解析
- char* ptr=input;
- char* argv[32]={NULL};
- int argc=0;
- while(*ptr!='\0'){
- if(*ptr==' '){//查找第一个指令字符
- ptr++;
- continue;
- }
- argv[argc]=ptr;//保存指令地址
- argc++;
- while(*ptr!='\0'&&*ptr!=' '){//将末尾的下一个位置替换为'\o'
- ptr++;
- }
- *ptr='\0';
- ptr++;
- }
- argv[argc]=NULL;//以空作为参数结尾
-
- //3.创建子进程,进行程序替换
- pid_t pid=fork();
- if(pid==0){//子进程
- execvp(argv[0],argv);
- exit(-1);//替换失败则退出子进程,否则子进程会成为第二个minishel
- }
- wait(NULL);//等待子进程退出
- }
- return 0;
- }
测试用例1:“ ls -a"
测试结果:

测试用例2:”ls -l “
测试结果:

测试用例3:”pwd"
测试结果:
