20155212 mybash的实现

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!\n");
    	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.\n",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= '\0';
    		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
    
  • 运行结果

  • 码云链接

posted @ 2017-10-21 10:54  0**  阅读(318)  评论(0编辑  收藏  举报