mybash的实现
题目
- 使用fork,exec,wait实现mybash
- 写出伪代码,产品代码和测试代码
- 发表知识理解,实现过程和问题解决的博客(包含代码托管链接)
准备
通过man命令了解fork、exec和wait
-
fork
-
exec
-
wait
编程实现
-
伪代码
while(1) { fgets(命令行输入); if(内置的shell命令) { 解释命令; } else if(可执行文件) { 新的子进程加载并运行文件; } }
-
产品代码
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <stdlib.h> #include <string.h> #define MAX 128 void eval(char *cmdline); int parseline(char *buf, char **argv); int builtin_command(char **argv); int main() { char cmdline[MAX]; printf("This is 20155212's bash! "); while(1) { printf("> "); fgets(cmdline, MAX, stdin); if(feof(stdin)) exit(0); eval(cmdline); } } void eval(char *cmdline) { char *argv[MAX]; char buf[MAX]; int bg; pid_t pid; strcpy(buf,cmdline); bg = parseline(buf,argv); if(argv[0]==NULL) return; if(!builtin_command(argv)) { if((pid=fork()) == 0) { if(execvp(argv[0],argv) < 0) { printf("%s : Command not found. ",argv[0]); exit(0); } } } if(!bg) { int status; if(waitpid(-1,&status,0) < 0) printf("waitfg: waitpid error!"); } else { printf("%d %s",pid, cmdline); return; } } int builtin_command(char **argv) { if(!strcmp(argv[0], "quit")) exit(0); if(!strcmp(argv[0],"&")) return 1; return 0; } int parseline(char *buf,char **argv) { char *delim; int argc; int bg; buf[strlen(buf)-1]=' '; while(*buf && (*buf == ' ')) buf++; argc=0; while( (delim = strchr(buf,' '))) { argv[argc++] = buf; *delim= ' '; buf = delim + 1; while(*buf && (*buf == ' ')) buf++; } argv[argc] = NULL; if(argc == 0) return 1; if((bg=(*argv[argc-1] == '&')) != 0) argv[--argc] = NULL; return bg; }
-
测试代码
ls ls -a git --version
-
运行结果