基于Linux下的MyBash命令解释器

项目介绍:⼀个⽤C语⾔实现的简单shell,可以接受⽤⼾输⼊的命令并执⾏操作,⽀持多管道和重 定向。

mybash---打造自己的命令解释器
目前我们Linux的系统默认的命令解释器是bash; 
命令解释器(也称为命令行解释器或shell)是计算机操作系统中的一个重要组件,它负责接收用户输入的命令,并解释和执行这些命令。其实命令解释器就是解析命令,执行命令,输出反馈;

1.命令的分类

内置命令和普通命令
1.内置命令:cd exit
2普通命令:ls pwd cp ps   等等
如果是普通命令,那么使用which是可以找到的,比如which ps;which ls;which pwd;which cp;
也就是普通命令是一个可执行程序.
但是我们找cd和exit是找不到的;  因为内置命令cd,exit等它是在bash本身实现的;
而bash也是一个可执行程序,比如:which bash;
简单来讲,就是普通命令是通过fork+exec实现的;而内置命令是bash自身通过调用相应的接口实现的;

2.项目框架

3.strtok的介绍

字符串分割函数

注意:
strtok线程不安全,原因就是函数实现使用了一个static的变量(指针记录下次分割的地址,再次调用要沿用上次的,所以需要静态变量).
在多线程中,如果两个线程都使用了strtok的话,这个变量的值就会被另一个线程不定期的进行修改. 

4.mybash.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>#define  ARG_MAX  10
char *get_cmd(char *buff,char *myargv[])
{if(buff==NULL||myargv==NULL){return NULL;}int i=0;char *s=strtok(buff," ");while(s!=NULL){myargv[i++]=s;s=strtok(NULL," ");}return myargv[0];
}
int main()
{while(1){printf("stu@loalhost:~$");fflush(stdout);char buff[128];fgets(buff,128,stdin);//ls  cd 路径名    cp  a.c  b.cchar *myargv[ARG_MAX]={0};buff[strlen(buff)-1]='\0';//注意这一句,自己练习一下调试char *cmd=get_cmd(buff,myargv);//得到命令cmd和它的参数(cmd和参数一起放在了myargv)if(cmd==NULL){continue;}else if(strcmp(cmd,"cd")==0){//}else if(strcmp(cmd,"exit")==0){// exit(0);break;}///else{//普通命令//fork+exec}}//exit(0);
}

 代码效果只能显示出命令,并不能执行命令

5.进行进一步的修改

 对具体函数进行填充

int main()
{while(1){//    printf("stu@localhost        ~$");printf_info();//fflush(stdout);char buff[128]={0};fgets(buff,128,stdin);//ls,ps -f,cp a.c b.cbuff[strlen(buff)-1]='\0';char *myargv[ARG_MAX]={0};char *cmd=get_cmd(buff,myargv);if(cmd==NULL){continue;}else    if(strcmp(cmd,"cd")==0){//...if(myargv[1]!=NULL){if(chdir(myargv[1])==-1){perror("cd err!\n");}}}else if(strcmp(cmd,"exit")==0){//exit(0);//OK,不建议break;}else{//fork+exec;run_cmd(cmd,myargv);}}//...exit(0);
}
void  printf_info()
{char *user_str="$";int user_id=getuid();if(user_id==0){user_str="#";}struct passwd *ptr=getpwuid(user_id);if(ptr==NULL){printf("mybash1.0>>  ");fflush(stdout);return ;}char hostname[128]={0};if(gethostname(hostname,128)==-1){printf("mybash1.0>>  ");fflush(stdout);return ;}char dir[256]={0};if(getcwd(dir,256)==NULL){printf("mybash1.0>>  ");fflush(stdout);return ;}printf("\033[1;32m%s@%s\033[0m  \033[1;34m %s\033[0m%s ",ptr->pw_name,hostname,dir,user_str);fflush(stdout);
}

一次对用户id ,主机名,当前目录初始化和定义 更改后效果

现在我们完善普通命令:

void run_cmd(char *path,char *myargv[])
{if(path==NULL ||myargv==NULL){return ;}pid_t pid=fork();if(pid==-1){return ;}if(pid==0){execvp(path,myargv);perror("execvp   error!\n");exit(0);}else{wait(NULL);}}

运行结果如下: 

 实际上应用了exevp函数,让操作系统自动调用了 /user/bin 文件里面的 各个普通命令实现mybash

完成一个借鸡生蛋的过程

6.我们也可以写出自己的二级制可执行程序,实现真正的mybash

例如 clear和pwd:

//clear.c#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main()
{printf("\033[2J\033[0;0H");
}//pwd.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main()
{char path[256]={0};if(getcwd(path,256)==NULL){   perror("getcwd  error!\n");exit(1);}   printf("%s\n",path);exit(0);
}

 并且更改路径

还应PATH_BIN的位置

#define PATH_BIN "/home/stu/quzijie/test15/mybin/"

这是我自己文件地址

void run_cmd(char *path,char *myargv[])
{if(path==NULL ||myargv==NULL){return ;}pid_t pid=fork();if(pid==-1){return ;}if(pid==0){// execvp(path,myargv);char pathname[128]={0};if(strncmp(path,"/",1)==0||strncmp(path,"./",2)==0){strcpy(pathname,path);}else{strcpy(pathname,PATH_BIN);strcat(pathname,path);}execv(pathname,myargv);perror("execvp   error!\n");exit(0);}

 结果如下:

 7.总结

基于Linux内核的命令解释程序(Shell),设计了⼀个⾃⼰的MyBash命令解释器。实现 了⼤致的程 序总框架,系统命令提⽰符显⽰,对⽤⼾输⼊命令的解析和执⾏,其中区别了系统的内 置命令和外置命令。具体实现了:显⽰指定⽬录下⽂件列表ls 和ls的部分携带参数例如“-l”“-a”、 显⽰当前位置的绝对路径pwd、清除 clear以及exit

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/899302.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux常见使用场景

一、文件查看与内容操作 ​1. cat ​作用&#xff1a;查看文件内容&#xff08;一次性输出全部内容&#xff09;。​常用选项&#xff1a; -n&#xff1a;显示行号。-b&#xff1a;仅对非空行显示行号。 ​示例&#xff1a; cat file.txt # 查看文件内容 cat -n fil…

Ingredient-oriented Multi-Degradation Learning for Image Restoration论文阅读

摘要&#xff1a;重点在于关联多个任务本质的联系。 不同恢复任务的关联性很重要。 揭示退化现象的内在机理联系很有意义。 多合一的方法能在单一模型中处理多种退化问题&#xff0c;可扩展性较差。 成分导向范式挖掘不同图像退化现象背后的物理规律或特征模式。 成分导向退化重…

禅道后台命令执行漏洞

漏洞简介 禅道是第一款国产的开源项目管理软件。它集产品管理、项目管理、质量管理、文档管理、 组织管理和事务管理于一体&#xff0c;是一款专业的研发项目管理软件&#xff0c;完整地覆盖了项目管理的核心流程。 禅道管理思想注重实效&#xff0c;功能完备丰富&#xff0c;…

密码学——知识问答

目录 1、阐述公开密钥算法的定义&#xff0c;结合RSA算法说明公钥密码的基本要求。 说明公钥与私钥两种密码学并举例与其应用 1. 公钥密码学&#xff08;非对称加密&#xff09;&#xff1a; 2. 私钥密码学&#xff08;对称加密&#xff09;&#xff1a; 对比公钥与私钥密码…

PDF多表格结构识别与跨表语义对齐:基于对抗迁移的鲁棒相似度度量模型

文章目录 一. 项目结构二.流程分析2.1 批处理器核心代码解析 三. 跨页表格相似度匹配原理3.1 表头内容相似度-特征向量归一化3.2 表头内容相似度-余弦相似度3.3 定时缓存清理 ocr扫描有其局限性。对于pdf文本类型这种pdfbox&#xff0c;aspose-pdf&#xff0c;spire直接提取文本…

es 3期 第27节-运用Script脚本实现复杂需求

#### 1.Elasticsearch是数据库&#xff0c;不是普通的Java应用程序&#xff0c;传统数据库需要的硬件资源同样需要&#xff0c;提升性能最有效的就是升级硬件。 #### 2.Elasticsearch是文档型数据库&#xff0c;不是关系型数据库&#xff0c;不具备严格的ACID事务特性&#xff…

23、web前端开发之html5(四)

十二. HTML5实践示例 前面我们详细讲解了HTML5的特点&#xff0c;包括语义化标签、增强的表单功能、多媒体元素&#xff08;如<video>和<audio>&#xff09;、Canvas绘图、SVG集成以及离线存储等。以下是一些详细的HTML5实践示例&#xff0c;展示如何使用HTML5的新…

海思烧录工具HITool电视盒子刷机详解

HiTool是华为开发的一款用于海思芯片设备的刷机和调试工具&#xff0c;可对搭载海思芯片的机顶盒、智能电视等设备进行固件烧录、参数配置等操作。以下为你详细介绍&#xff1a; 功能用途 固件烧录&#xff1a;这是HiTool最主要的功能之一。它能够将下载好的适配固件文件烧录到…

软考中级-软件设计师 23种设计模式(内含详细解析)

23种设计模式 &#x1f3af; 创建型设计模式&#x1f4cc; 抽象工厂&#xff08;Abstract Factory&#xff09; 设计模式&#x1f4cc; 工厂方法&#xff08;Factory Method&#xff09;设计模式&#x1f4cc; 单例&#xff08;Singleton&#xff09;设计模式&#x1f4cc; 生成…

thinkphp8.0\swoole的websocket应用

环境&#xff1a;centOS7.9、php8.3、thinkphp8.0\think-swoole4.1 我用的官方think-swoole插件 第一步&#xff1a;根据官方文档&#xff0c;需要安装此扩展插件 composer require topthink/think-swoole 第二步&#xff1a;在根目录下config文件夹下编辑swoole.php配置文…

Ubuntu服务器挂载时遇到文件系统错误怎么办

在Ubuntu服务器上挂载分区时&#xff0c;如果遇到文件系统错误&#xff0c;通常可能是由于磁盘损坏、文件系统损坏、不正确的卸载等原因造成的。以下是详细的排查与修复步骤&#xff1a; 一、查看错误信息 首先&#xff0c;尝试手动挂载并观察具体错误&#xff1a; sudo mount …

【设计模式】策略模式(Strategy Pattern)详解

策略模式&#xff08;Strategy Pattern&#xff09;详解 一、策略模式的定义 策略模式&#xff08;Strategy Pattern&#xff09;是一种行为型设计模式&#xff0c;它定义了一组算法&#xff0c;将每个算法封装起来&#xff0c;并使它们可以相互替换&#xff0c;从而让算法的…

软考笔记5——软件工程基础知识

第五章节——软件工程基础知识 软件工程基础知识 第五章节——软件工程基础知识一、软件工程概述1. 计算机软件2. 软件工程基本原理3. 软件生命周期4. 软件过程 二、软件过程模型1. 瀑布模型2. 增量模型3. 演化模型&#xff08;原型模型、螺旋模型)4. 喷泉模型5. 基于构建的开发…

Vim 实用指南

导航 简介Vim 的来历Vim 语言 Vim 的三种模式Normal&#xff08;普通模式&#xff09;Insert&#xff08;插入模式&#xff09;Visual&#xff08;可视模式&#xff09;三种模式转换 普通模式实用技巧说明复制当前行并粘贴使用上一个命令撤销上一个操作最常用的跳转命令查找对应…

Git入门——常用指令汇总

以下是一份精心整理的 Git常用指令速查表&#xff0c;基本覆盖日常开发使用场景&#xff0c;建议收藏备用&#x1f447; &#x1f527; 环境配置 指令作用git config --global user.name "你的名字"设置全局用户名git config --global user.email "你的邮箱&qu…

常见中间件漏洞攻略-Jboss篇

一、CVE-2015-7501-Jboss JMXInvokerServlet 反序列化漏洞 第一步&#xff1a;开启靶场 第二步&#xff1a;访问该接口&#xff0c;发现直接下载&#xff0c;说明接⼝开放&#xff0c;此接⼝存在反序列化漏洞 http://47.103.81.25:8080/invoker/JMXInvokerServlet 第三步&…

播放本地视频-实现视频画廊功能

实现一个视频画廊&#xff0c;播放本地视频 可以切换不同视频的功能 文章目录 需求&#xff1a;场景实现方案遇到的坑播放器选择界面显示不全视频友好显示问题缓存 总结 需求&#xff1a; 实现一个视频画廊&#xff0c;播放本地视频 可以切换不同视频的功能 场景 图片画廊的…

从零构建大语言模型全栈开发指南:第二部分:模型架构设计与实现-2.2.2文本生成逻辑:Top-k采样与温度控制

👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 2.2.2 文本生成逻辑:Top-k采样与温度控制1. 文本生成的核心挑战与数学框架1.1 自回归生成的基本流程2. `Top-k`采样原理与工程实现2.1 数学定义与算法流程2.2 PyTorch实现优化3. 温度控制的数学本质与参…

为什么后端接口返回数字类型1.00前端会取到1?

这得从axios中得默认值说起&#xff1a; Axios 的 transformResponse axios 在接收到服务器的响应后&#xff0c;会通过一系列的转换函数&#xff08;transformResponse&#xff09;来处理响应数据&#xff0c;使其适合在应用程序中使用。默认情况下&#xff0c;axios 的 tran…

【C++游戏引擎开发】《线性代数》(2):矩阵加减法与SIMD集成

一、矩阵加减法数学原理 1.1 定义 ​逐元素操作:运算仅针对相同位置的元素,不涉及矩阵乘法或行列变换。​交换律与结合律: 加法满足交换律(A + B = B + A)和结合律( ( A + B ) + C = A + ( B + C ) )。 ​减法不满足交换律(A − B ≠ B − A)。1.2 公式 ​ C i j = …