完成一个简易Shell 上文完成了进程的部分知识点本文将会进行一次shell编写会详细解释每行代码的作用及其逻辑。最后给出运行结果#includesys/types.h#includesys/wait.h#includestdio.h#includestdlib.h#includeunistd.h#includestring.h#defineMAX_LINE1024//命令最大长度#defineMAX_ARGS64//命令参数最大长度//读取用户输入的命令voidget_command(char*cmd);//分别将其命令为argv数组格式intsplit_command(char*cmd,char**args);//执行命令voidrun_command(char**argv);intmain(){//定义字符数组存储用户输入的命令以及一个指针数组存储命令参数charcmd[MAX_LINE];char*argv[MAX_ARGS];//无限循环直至exit输入while(1){//打印命令提示符告诉用户输入命令printf(myshell);//刷新缓冲区确保提示符被立即显示fflush(stdout);//调用函数读取用户输入的命令get_command(cmd);//如果用户什么都没输入跳过本次循环if(strlen(cmd)0)continue;//调用函数把输入的命令转化为参数列表split_command(cmd,argv);//内置内存处理输入exit退出shellif(strcmp(argv[0],exit)0){printf(Bye!\n);exit(0);}//执行用户输入的外部命令run_command(argv);}}//函数功能读取用户输入的命令去除末尾换行符//参数cmd,用来存储读取到的命令字符串voidget_command(char*cmd){fgets(cmd,MAX_LINE,stdin);cmd[strcspn(cmd,\n)]\0;}//这里把用户输入的字符串进行分割·以空格为分隔符//存储到args数组中并返回参数的数量//cmd:用户输入的原始字符串//args:存储分割字符串的参数数组//返回值为参数的个数intsplit_command(char*cmd,char**args){//这里的参数个数为0intargc0;//使用strtok分割字符串//从cmd开始按 空格 和 制表符 分割返回第一个参数char*pstrtok(cmd, );//循环分割直到参数不足或者达到上限while(p!NULLargcMAX_ARGS-1){//将分割后得到的字符串放进字符数组中//并将参数个数加1args[argc]p;//继续分割直到没有更多的参数pstrtok(NULL, );}//最后一个设置为NULL表示参数列表的结束args[argc]NULL;//返回参数个数returnargc;}//函数功能执行用户输入的命令//argv参数列表包含命令和其他参数//通过创建子进程来执行命令父进程等待子进程完成//pid_t进程id类型fork()函数返回值的类型//pid为子进程id,如果小于0表示创建子进程失败//如果等于0表示当前是子进程//如果大于0表示当前是父进程pid为子进程的idvoidrun_command(char**argv){//创建子进程IDpid_tpidfork();if(pid0){perror(fork failed);exit(1);}elseif(pid0){execvp(argv[0],argv);perror(exec failed);exit(1);}//父进程等待子进程yo完成//status用来存储子进程退出状态else{intstatus;//wait函数等待子进程结束获取其退出状态wait(status);}}