40多行实现一个非常简单的shell

简单的shell的实现

目的:主要就是为了加深对shell的底层原理的理解


可以通过接口可以获取到这些主机名等等这里直接就用字符串打印了

  • 当我们打开一个c文件默认就打开了三个输入输出流:stdin(标准输入),stdout(标准输出),stderr(标准错误)

  1. 打印提示符


    在这里插入图片描述

  2. 获取命令字符串


    但是只是这样会有一个问题他会读取一个\n,也就是出现了上面的ls -a -l -n下面空了一行,如何去掉这一行呢?

    commed[strlen(commed)-1]='\0';//即可
    //strlen(commed)-1指向的是\n,这里是把\n替换成\0即可解决问题
    
    • fgets()函数
  3. 解析命令字符串

    • strtok()

    • 解析完成就可以直接创建子进程来运行了

    • 出现这种现象的主要原因是我们通过子进程来执行cd命令,子进程是回退了,可是并不会影响父进程,pwd显示的是当前进程的路径

    • cd这种命令和ls这种命令不一样,cd这种属于内建命令,他是需要父进程来执行的,而不是子进程去执行;其他的属于第三方命令,由子进程执行(/usr/bin下面看到的都是第三方命令)

    • 所以这个程序就需要步骤4

  4. 检测命令是否是需要shell本身执行的,内建命令

    这里就需要一个函数chdir来更改路径

    到这里简易的shell就完成了,有一个小问题,思考一下函数和进程之前有没有相似性呢?—>答案是有的
    exec/exit就像call/return一个C程序有很多函数组成。一个函数可以调用另外一个函数,同时传递给它一些参数。被调用的函数执行一定的
    操作,然后返回一个值。每个函数都有他的局部变量,不同的函数通过call/return系统进行通信。这种通过参数和返回值在拥有私有数据的函数间通信的模式是结构化程序设计的基础
    一个C程序可以fork/exec另一个程序,并传给它一些参数。这个被调用的程序执行一定的操作,然后通过exit(n)来返回值。调用它的进程可以通过wait来获取exit的返回值。

附代码

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>
#define NUM 128
#define NUM_CMD 64
int main()
{
  char commed[NUM];
  //我们要先理解,shell要是自己实现他一定是一个死循环的程序,这样才能够不断的读取命令并执行
  //1.就是获取字符串,c语言的获取字符串可以用fgets
  for(;;)
  {
    printf("[xifeng@VM-16-14-centos 简易版的shell]$ ");
    fflush(stdout);
    commed[0]=0;//O(1)时间复杂度清空字符串
    //2.获取字符串
    fgets(commed,NUM,stdin);
    commed[strlen(commed)-1]='\0';//这里是把\n给替换成\0
    //3.解析字符串
    char* argv[NUM_CMD]={NULL};
    argv[0]=strtok(commed," ");
    int i=1;
    while(argv[i]=strtok(NULL," "))
    {
      ++i;
    }
    //读取之后就需要能够解析代码,因为我们解析出来的指令并没有带路径,所以我们能够选用的exec*函数一定需要带p的,而且之前已经用数组获取了参数,则可以直接使用execvp
   //4.但是在运行命令之前需要先判断是否是内建命令
   //如果是cd命令就执行路径切换用父进程来执行
    if(strcmp(argv[0],"cd")==0 && argv[1]!=NULL)//相等,并且带有参数
    {
      chdir(argv[1]);
    }
    if(fork()==0)
    {
      execvp(argv[0],argv);
      exit(1);
    }
    int status=0;
    waitpid(-1,&status,0);
    printf("exit code:%d\n",(status>>8)&0xFF);
   }
   return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值