minishell 程序的简单实现---bash

minishell 程序

  1. 使用到的技术:创建子进程,进程替换,进程等待
  2. 理解bash(命令行解释器)本身也是一个程序,在命令行解释器中输入ls,pwd,mv,cp等这些命令的时候,其实bash也是创建了一个子进程,让子进程去进程程序替换执行相应的命令程序。
  3. 实现
    3.1 从标准输入当中获取用户输入的命令
    3.2 创建子进程,让子进程进行进程替换,执行刚刚从标准输入读进来的命令
    3.3 父进程需要子进程进行进程程序替换的时候,父进程进行进程等待,防止子进程变成僵尸进程
    在这里插入图片描述
    图解:
    在这里插入图片描述
  #include <stdio.h>                                                                                 
  #include <unistd.h>    
  #include <string.h>       
  #include <ctype.h>    
  #include <stdlib.h>    
  #include <sys/wait.h>            
           
  char g_command[1024];                      
           
  int Getcommand()    
  {    
      printf("[zs@localhost minishell]");    
      fflush(stdout);    
      memset(g_command, '\0', sizeof(g_command));//初始化    
      if(fgets(g_command, sizeof(g_command) -1, stdin) == NULL)    
      {                             
          perror("fgets perror");    
          return -1;    
      }                    
      printf("%s\n", g_command);    
      return 0;             
  }   
          
  int ExecCommand(char* argv[])
  {
      //创建子进程
      //让子进程进行程序替换
      if(argv[0] == NULL)
      {
          printf("ExecCommand failed\n");
          return -1;
       }
     
      pid_t pid = fork();
      if(pid < 0)
      {
          perror("fork");
          return -1;
      }
      else if(pid == 0)
      {
          //child -->进程程序替换
		  execvp(argv[0], argv);
          //如果调用了execvp,还能走到下面的逻辑,则表示替换失败了
          //将没有替换成功的子进程杀掉                                                               
          exit(0);
      }
   else
      {
          //father -->进程等待,防止子进程变成僵尸进程
          waitpid(pid, NULL, 0);
      }
      return 0;
  }
  
  int Dealcommand(char* command)
  {
      //ls -l ==> ls 可执行程序 -l 传递给ls的命令行参数
      //1. 切分读进来的字符串,区分一下什么是可执行程序
      //  1.1切分出来的第一个字符串就是可执行程序
      //  1.2后面的都是命令行参数进行切割
      //  1.3用空格作为分隔符来进行切割
      int argc = 0;
      char* argv[1024] = {0};
      while(*command)
      {
          //判断当前的字符是否是空格 或者 \0,如不是就保存在char*
          if(!isspace(*command) && *command != '\0')
          {
              argv[argc] = command;  
              argc++;
  
              while(!isspace(*command)&& *command != '\0')
              {
                  command++;
              }
              *command = '\0';//将非字符的全部用\0代替
          }
          command++;//向后寻找
      }
  
      argv[argc] = NULL;
  
      int i = 0;
      for(i = 0; i < argc; i++)
      {                                                                                              
          printf("%d:%s\n", i , argv[i]);
      }
  }
  
  int main()
  {
      while(1)
      {
          //1.获取用户数日的命令
          if(Getcommand() == -1)
          {
              continue;
          }
          //2.创建子进程
          //3.让子进程进行程序替换
          //4.进程等待
          Dealcommand(g_command);
      }
  
      return 0;
  }   

结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值