【linux课设】自主实现shell命令行解释器

shell和bash的关系

shell是命令解释器,它接收用户的命令并将其传递给内核去执行。bash,即GNU Bourne-Again Shell,是shell的一种实现方式,也是大多数linux系统下默认的shell。

bash的原理

大多数的指令进程(除了内建命令)都是bash的子进程。当我们要执行一条类似ls -a指令时,bash会提前fork出一个子进程,然后让子进程去执行指令。这是我们进程程序替换的思想。当然,中间的过程涉及到进程创建、虚拟内存、进程替换的细节,本篇文章不做叙述,感兴趣的可以去看我之前的博客,希望能对你有帮助。

我们可以画出bash进程执行指令的过程图来帮助理解:
在这里插入图片描述

在上图中,bash几乎一直在循环做以下动作:

1.获取指令
2.解析命令行
3.fork创建子进程
4.命令程序替换子进程
5.等待子进程终止

既然知道了bash的基本原理,我们同样也可以模拟以上动作来写一个mini版的shell

代码实现

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<string.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<errno.h>#define SIZE 100
#define COMMAND_SIZE 200
#define ZEOR '\0'
#define ARGV_NUM 32
#define SKIP " "
#define SkipPath(p) do{p+=strlen(p)-1; while(*p!='/'){p--;}}while(0)char* gArgv[ARGV_NUM];//指令参数
char cwd[SIZE*2];//当前路径的环境变量键值对
int lastcode=0;const char* GetUserName(){//获取环境变量中的值const char* name=getenv("USER");if(name==NULL){return "None";}return name;
}const char* GetHome(){//获取家目录const char* home=getenv("HOME");if(home==NULL){return "/";}return home;
}const char* GetHostHome(){//获取主机名const char* hostname=getenv("HOSTNAME");if(hostname==NULL){return "None";}return hostname;
}const char* GetCwd(){//获取当前路径const char* cwd=getenv("PWD");if(cwd==NULL){return "None";}return cwd;
}//输出命令行
void MakeCommandLineAndPrint(){char line[SIZE];const char* name=GetUserName();const  char* hostname=GetHostHome();const char* cwd=GetCwd();SkipPath(cwd);snprintf(line,sizeof(line),"[%s@%s %s]> ",name,hostname,cwd=strlen(cwd)==1?"/":cwd+1);printf("%s",line);fflush(stdout);
}
//获取用户命令行
int GetUserCommand(char command[],size_t n){char* s=fgets(command,n,stdin);if(s==NULL)return -1;command[strlen(command)-1]=ZEOR;return (int)strlen(command);
}//命令行分割,获取命令行参数列表
void SplitCommand(char command[],size_t n){gArgv[0]=strtok(command,SKIP);size_t index=1;char* t=gArgv[0];while(t!=NULL){t=strtok(NULL,SKIP);gArgv[index++]=t;}//size_t i=0;//for(;i<index;i++){//  printf("%s\n",gArgv[i]);//}
}//cd内建命令
void Cd(){const char* path=gArgv[1];if(path==NULL){path=GetHome();}//更新当前工作目录chdir(path);//修改当前进程的工作路径//更新环境变量char t[SIZE*2];getcwd(t,sizeof(t));snprintf(cwd,sizeof(cwd),"PWD=%s",t);putenv(cwd);
}//查看是否是内建命令
int CheckBuiltIn(){int yes=0;const char* cmd=gArgv[0];if(strcmp(cmd,"cd")==0){yes=1;Cd();}return yes;
}
// 处理创建子进程失败
void Die(){exit(1);
}
//执行指令
void ExeCommand(){ pid_t id=fork();if(id<0){Die();}if(id==0){//childexecvp(gArgv[0],gArgv);exit(errno);}else{int status=0;pid_t res=waitpid(id,&status,0);if(res>0){lastcode=WEXITSTATUS(status);//获取子进程退出码信息if(WIFEXITED(status)){if(lastcode!=0) printf("%s:%s:%d\n",gArgv[0],strerror(lastcode),lastcode);}}}
}int main(){int quit=0;while(!quit){//1.输出一个命令行MakeCommandLineAndPrint();//2.获取用户命令char command[COMMAND_SIZE];int n= GetUserCommand(command,sizeof(command));if(n<=0)return 1;//输入指令不合法// printf("%s\n",command);//3.命令行字符串分割SplitCommand(command,sizeof(command));//4.查看命令是否是内建命令int flag=CheckBuiltIn();if(flag)continue;//5.执行指令ExeCommand();}return 0;
}

运用进程创建,进程替换的原理,基本模拟了shell解释命令的过程。

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

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

相关文章

窥探未来:Web3如何颠覆传统互联网

随着科技的迅速发展&#xff0c;Web3正逐渐成为人们关注的焦点。与传统的Web2相比&#xff0c;Web3代表了一种全新的互联网模式&#xff0c;其潜力和影响力引发了人们对未来的期待和探索。本文将深入探讨Web3如何颠覆传统互联网的各个方面&#xff0c;并展望其可能带来的未来变…

Docker搭建LNMP环境实战(08):安装php-fpm

1、编写php测试文件 在文件夹&#xff1a;/mnt/hgfs/dockers/test_site/www目录下创建文件&#xff1a;test.php&#xff0c;内容为&#xff1a; <?phpecho "hello world!!!!!! From test.php"; ?>2、编写php-fpm部署配置文件 在文件夹&#xff1a;/mnt/h…

基于单片机寻迹巡线避障智能小车系统设计

**单片机设计介绍&#xff0c;基于单片机寻迹巡线避障智能小车系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机寻迹巡线避障智能小车系统设计是一个结合了硬件与软件技术的综合性项目。该系统的目标是设计一款…

AMEYA360代理 | 江苏长晶科技FST2.0高性能 IGBT产品介绍

江苏长晶科技股份有限公司是一家专业从事半导体产品研发、生产和销售的企业。自2019年起&#xff0c;连续4年被中国半导体行业协会评为 “功率器件十强企业”。2021年开始自主研发有着“工业CPU”之称的IGBT&#xff0c;截至2023年Q3在家电/工业/新能源等行业实现8款产品市场应…

【MySQL】DML的表操作详解:添加数据&修改数据&删除数据(可cv例题语句)

前言 大家好吖&#xff0c;欢迎来到 YY 滴MySQL系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C Linux的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的…

政安晨:【Keras机器学习实践要点】(九)—— 保存、序列化和导出模型

目录 介绍 如何保存和加载模型 保存一个Keras模型 装回模型 设置 保存 例子&#xff1a; 自定义对象 向 load_model() 传递自定义对象 使用自定义对象范围 模型序列化 APIs 内存模型克隆 任意对象序列化和反序列化 保存模型权重 内存中的权重传递接口 无状态层…

阿里云Salesforce CRM功能差异列表 - Winter‘24

阉割版的阿里云Salesforce由于技术和监管等因素与国际版的Salesforce差距很大&#xff01; 一、Winter‘ 24版差异概况&#xff1a; 1.1. 主要版本&#xff1a; 阿里云上的 Salesforce 提供两个版本&#xff0c;用于生产用途的 CN 版本&#xff08;CN Edition&#xff09;和用…

20240329-科技咨询:比亚迪第五代DMi;央视AI《周处除三害》;带屏幕苹果耳机爆火

一、比亚迪5月份即将推出第五代DMi技术 近日&#xff0c;比亚迪举行了2023年财报投资人沟通会。会议纪要显示&#xff0c;比亚迪董事长王传福在会上透露&#xff0c;今年5月将推出第五代DMI混动技术&#xff0c;预计馈电油耗将降至2.9升/百公里&#xff0c;而满油满电续航将达…

Matlab-写入mhd和raw医学图像处理格式文件

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 mhd和raw是什么&#xff1f; MHD&#xff08;MetaImage&#xff09;和RAW&#xff08;Raw Image Data&#xff09;是用于医学图像…

kubernetes-networkpolicies网络策略问题

kubernetes-networkpolicies网络策略问题 问题描述 重点重点重点&#xff0c;查看我的博客CKA考题&#xff0c;里面能找到解决方法 1.部署prometheus监控的时候&#xff0c;都部署成功&#xff0c;但是web访问503-504超时 2.添加ingress的时候也是访问不到&#xff0c;其他命…

HarmonyOS实战开发-如何实现一个简单的电子相册应用开发

介绍 本篇Codelab介绍了如何实现一个简单的电子相册应用的开发&#xff0c;主要功能包括&#xff1a; 实现首页顶部的轮播效果。实现页面跳转时共享元素的转场动画效果。实现通过手势控制图片的放大、缩小、左右滑动查看细节等效果。 相关概念 Swiper&#xff1a;滑块视图容…

Eclipse新建java类的操作流程

一、在左侧空白区域&#xff0c;点击鼠标右键。 二、点击new&#xff0c;选择Java Project &#xff08;由于这里不知道怎么截图&#xff0c;就用手机拍了一张&#xff0c;希望不要介意&#xff09; 三、 给project文件起个名字&#xff0c;其他都不用管&#xff0c;点击Finis…

YoloV8实战:使用YoloV8检测钢材表面缺陷

摘要 本文讲解一下实战,使用YoloV8检测钢材表面缺陷。起因是有粉丝搞不定这个数据集,检测的时候出现了不收敛的情况。所以,给大家讲讲如何去做。 不收敛的原因 一般遇到不收敛的情况,就是数据转化的时候出错了,大家可以打开runs下面的训练日志,观察一下是否正常。 如…

数据结构(六)——图

六、图 6.1 图的基本概念 图的定义 图&#xff1a;图G由顶点集V和边集E组成&#xff0c;记为G (V, E)&#xff0c;其中V(G)表示图G中顶点的有限非空集&#xff1b;E(G) 表示图G中顶点之间的关系&#xff08;边&#xff09;集合。若V {v1, v2, … , vn}&#xff0c;则用|V|…

快排(六大排序)

快速排序 快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法&#xff0c;其基本思想为&#xff1a;任取待排序元素序列中的某元素作为基准值&#xff0c;按照该排序码将待排序集合分割成两子序列&#xff0c;左子序列中所有元素均小于基准值&#xff0c;右子序列中所…

Java 扫描某包下所有类的注解并获得注解值

背景 &#xff1a; 需求 需要获取某个包下的所有的注解 并不是全部项目的 所以 只用针对某个包 进行扫描 获取注解 数据就行 百度了一圈 spring boot 没有自带的 获取注解集合的方法 在看 php 中 hyperf 框架 看到了 这个方法 就是因为 我需求是 php 和java 合体 微服务开发 …

华为云亮相KubeCon EU 2024,以持续开源创新开启智能时代

3月21日&#xff0c;在巴黎举办的云原生顶级峰会KubeCon EU 2024上 &#xff0c;华为云首席架构师顾炯炯在“Cloud Native x AI&#xff1a;以持续开源创新开启智能时代”的主题演讲中指出&#xff0c;云原生和AI技术的融合&#xff0c;是推动产业深刻变革的关键所在。华为云将…

GAMES Webinar 288-VR/AR专题-陆峰-混合现实中的多模态自然人机交互

感知交互增强智能 研究室虚拟现实技术与系统国家重点实验室&#xff0c;北京航空航天大学计算医学研究所&#xff0c;大数据精准医疗北京市高精尖创新中心 Perception & Hybrid Interaction (PHI) for Augmented & Affective Intelligence (A2I) We are working on v…

【微服务】Gateway

文章目录 1.基本介绍官方文档&#xff1a;https://springdoc.cn/spring-cloud-gateway/#gateway-starter1.引出网关2.使用网关服务架构图3.Gateway网络拓扑图&#xff08;背下来&#xff09;4.Gateway特性5.Gateway核心组件1.基本介绍2.断言3.过滤 6.Gateway工作机制 2.搭建Gat…

FastAPI+React全栈开发08 安装MongoDB

Chapter02 Setting Up the Document Store with MongoDB 08 Installing MongoDB and friends FastAPIReact全栈开发08 安装MongoDB The MongoDB ecosystem is composed of different pieces of software, and I remember that when I was starting to play with it, there w…