Linux【实现一个简单的minishell】

shell

shell 是命令行解释器,我们平常在使用操作系统的时候,是不能直接操作内核的,shell可以将用户的命令翻译给kernel处理,同时也可以将核心的处理结果翻译给用户。
我们可以举个例子来理解一下,shell就相当于我们班班花的同桌,我想约班花周末去看电影,但又难以启齿,就让班花的同桌帮我们问班花是否愿意,然后班花的同桌再将班花的回答转达给我,我们只需要把我们要问的告诉班花的同桌,最终得到结果,至于她是怎么给班花说的这个我们不关心。

在Linux中,shell(班花的同桌)主要是对用户的指令(我想约班花周末看电影)进行解析,解析指令给Linux内核(班花),然后再将内核运行之后的结果返回给用户

今天我们就在Linux下实现一个简单的minishell,来完成一些简单的操作
实现minishell的步骤:

  1. 获取用户的指令
  2. 解析用户的指令
  3. 创建一个子进程
  4. 将子进程替换成我们要解析的指令对应的函数
  5. 父进程等待子进程退出,避免产生僵尸进程

程序替换:

通常我们使用fork函数创建一个子进程来执行和父进程一样的程序,但如果向让子进程执行和父进程不一样的代码分支,就需要调用exec函数来将子进程的原有的程序替换成我们想要执行的程序

exec函数族

int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg,..., char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execve(const char *file, char *const argv[],char *const envp[]);

有p和没有p的区别:要加载的程序是否需要确定给出所在路径
v和l的区别:程序运行参数是函数的参数平铺或者直接组织成为字符串指针数组给与
带e和不带e的区别:要运行的程序是否需要重新定义环境变量

l表示list,代表参数采用列表
v表示vector,代表参数使用数组
p表示path,代表自动搜索环境变量PATH
e表示env,代表需要自己维护环境变量

minishell的实现:
代码:

  1 #include<stdio.h>                                                                                                                             
  2 #include<unistd.h>
  3 #include<string.h>
  4 #include<stdlib.h>
  5 #include<sys/wait.h>
  6 #include<ctype.h>
  7 
  8 
  9 int main() {
 10   while(1) {
 11     printf("[MXS@localhost]$");
 12     fflush(stdout);
 13     char tmp[1024]={0};
 14     scanf("%[^\n]%*c",tmp);
 15     //获取一个连续的字符串%[^\n],从标准输入缓冲区取数据直到遇到\n截止,
 16     //%*c:将缓冲区中剩下的\n取出来;否则会造成死循环
 17 
 18     char *ptr=tmp;
 19     int argc=0;
 20     char *argv[32]={NULL};
 21     while(*ptr != '\0') {
 22       if(!isspace(*ptr)) {
 23         argv[argc]=ptr;
 24         argc++;
 25         while(!isspace(*ptr) && *ptr != '\0')
  26               ptr++;
 27         *ptr='\0';
 28         ptr++;
 29         continue;
 30       }
 31       ptr++;
 32     }
 33     argv[argc]=NULL;
 34     
 35     if(!strcmp(argv[0],"cd")){
 36       //改变当前工作路径
 37       chdir(argv[1]);
 38       continue;
 39     }
 40 
 41     int pid=fork();
 42     if(pid==0) {
 43       execvp(argv[0],argv);
 44       //若子进程替换程序失败,则直接退出,因为不需要多个shell
 45       exit(0);
 46     }
 47     wait(NULL);
 48   }
 49   return 0;
 50 }   

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

这样我们就实现了一个简单的命令行解释器,需要注意的是shell中处理外部命令是通过创建子进程后程序替换完成功能;还有一部分命令是内建命令,也就是shell自身实现的功能,比如cd改变当前所在路径

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值