Linux--模拟实现shell

#include 
#include 
#include 
#include 
#include 
#include 

#define NUM 1024
#define SIZE 32
#define SEP " "

//保存打散之后的命令行字符串
char* g_argv[SIZE];
//保存完整的命令行字符串
char cmd_line[NUM];
//shell运行原理:通过让子进程执行命令,父进程等待&&解析命令
int main()
{
  //0.命令行解释器,一定是一个常驻内存的进程,不退出
  while(1)
  {
    //1.打印出提示信息 [qkj@localhost myshell]#
    printf("[qkj@localhost myshell]# ");
    fflush(stdout);
    memset(cmd_line,'\0',sizeof(cmd_line));
    //2.获取用户的输入
    if(fgets(cmd_line,sizeof cmd_line,stdin)==NULL)
    {
      continue;
    }
    cmd_line[strlen(cmd_line)-1]='\0';//将输入的\n换成\0
    //printf("echo: %s\n",cmd_line);
    
    //3.命令行字符串解析:"ls -a -l -i" -> "ls" "-a" "-l" "-i"
    g_argv[0]=strtok(cmd_line,SEP);//第一次调用,要传入原始字符串
    int index=1;
    if(strcmp(g_argv[0],"ls")==0)//给ls指令的结果添颜色
    {
      g_argv[index++] = "--color=auto";
    }
    if(strcmp(g_argv[0],"ll")==0)//解决识别不了ll是ls -l别名的问题
    {
      g_argv[0]="ls";
      g_argv[index++]="-l";
      g_argv[index++] = "--color=auto";
    }
    while(g_argv[index++] = strtok(NULL,SEP));//第二次,如果还要解析原始字符串,传入NULL

    //for debug
    //for(index=0;g_argv[index];index++)
      //printf("g_argv[%d]: %s\n",index,g_argv[index]);
    //4.TODO,内置命令,让父进程(shell)自己执行的命令,我们叫做内置命令/内建命令
    //内建命令本质其实就是shell中的一个函数调用
    if(strcmp(g_argv[0],"cd")==0)//not child execute,father execute
    {
      if(g_argv[1]!=NULL) chdir(g_argv[1]);//cd path, cd ..
      continue;
    }

    //5.fork()
    pid_t id=fork();
    if(id == 0)//child
    {
      printf("下面功能让子进程执行的\n");
      execvp(g_argv[0],g_argv);
      exit(1);
    }
    //father
    int status=0;
    pid_t ret=waitpid(id,&status,0);
    if(ret>0) printf("exit code: %d\n",WEXITSTATUS(status)); 

  }
}

你可能感兴趣的:(Linux,linux)