简易版shell

我门用exec函数来写一个简易版的shell

我们先理一下步骤:
  1. 首先将输入的在命令解析为一个一个的命令,就去掉空格,我们可以使用strtok函数(创建命令)
  2. 然后在创建一个进程让它去执行这个命令(解析命令并执行)
  3. 父进程等待进程结束了返回之后,继续执行原来的代码
#include <stdio.h>
#include <sys/types.h>
#include <pwd.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <wait.h>


void GetLocalName()
{
  struct passwd *pass;
  pass = getpwuid(getuid());
  printf("[%s@",pass->pw_name);
}


void GetHostName()
{
  char name[128];
  //将得到的主机名放在数组里
  gethostname(name,sizeof(name)-1);
  printf("%s",name);
}

void GetDir()
{
  char pwd[256];
  getcwd(pwd,sizeof(pwd)-1);
  int len = strlen(pwd);
  //得到该程序执行的根目录
  char *p = pwd + len -1;
  while(*p != '/'&& len--)
  {
    p--;
  }
  p++;
  printf(" %s]@",p);

}
int main()
{
  while(1)
  {
    //打印目录信息和主机名和什么地址
    GetLocalName();
    GetHostName();
    GetDir();
    //刷新输出缓冲区
    fflush(stdout);

    char buf[1024];
    ssize_t s = read(0,buf,1024);

    //读到了字符
    if(s > 0)
    {
      //在最后添一个'\0',使之成为字符串
      buf[s-1]  ='\0';
    }
    else
    {
      perror("read error!");
    }

    //将读到的字符按空格拆分放入一个指针数组    
    char *argv[100] = {NULL};
    char *p = strtok(buf," ");
    int size = 0;
    while(p != NULL)
    {
      argv[size++] = p;
      p = strtok(NULL," ");
    }
    argv[size] =  NULL;

    //开始让子进程去执行我们输入的命令,执行完成之后,再返回执行父进程
    pid_t id = fork();
    if(id == 0)
    {
      //子进程
      // exec
      execvp(argv[0],argv);
      exit(1);
    }
    else if(id < 0)
    {
      perror("fork error!\n");
    }
    else
    {
      //父进程等待子进程执行完再继续执行父进程
      int status = 0;
      pid_t ret = waitpid(id,&status,0);
      if(ret > 0 && WIFEXITED(status))
      {}
      else
      {
        perror("waitpid error!\n");
      }
    }
  }
}


这个代码其实逻辑也比较简单,但是这个shell真的是太简单了,没有管道和重定向,还有一些内键指令也没有,但是这只是搭建出来了一个shell的结构,接下来这些东西还要自己去添加



猜你喜欢

转载自blog.csdn.net/qq_36767247/article/details/80379134