linux中实现自己的bash

🐶博主主页:@ᰔᩚ. 一怀明月ꦿ 

❤️‍🔥专栏系列:线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C++

🔥座右铭:“不要等到什么都没有了,才下定决心去做”

🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀

        感觉,有很久都没有写博客,主要是最近学的内容难以理解,所以时间不太充足,就没有写博客的时间,今天为什么要这一篇文章呢?主要是我感觉实现一个自己的命令行小程序还是比较有趣的。

         我们平时都是在linux的shell命令行上直接输入指令,有没有想过自己也可以去实现一个,自己的bash呢?

        那就让我们一起来探索属于自己自己的bash 

这次我就直接给出源代码,没有把其中的方法,单独拿出来分析,我主要觉得那样有点显得代码冗余,其实也不用担心看不懂,我在源码中加了很多注释,大家也不怕看不懂。其实这样做还有一个好处,就是我们可以直接复制到我们的linux文件中,直接运行。 

源码 

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>#define SIZE 100 //用于定义命令的最大长度
#define NUM 1024 //用于定义命令参数的最多个数
#define SEP " " //分割字符的时候,默认以空格作为分隔符char _cwd[1024]; //用于存储PWD的环境变量
char env_val[1024]; //用于自定义一个环境变量,这里有一个缺点,就是env_val是一个数组,只能添加一个自定义的环境变量,下次添加时,就会覆盖上次添加的环境变量
int lastcode=0; //用于定义最近一个进程的退出码//获取用户名字
const char* getUsername(void)
{const char* name=getenv("HOME");//getenv如果没有获取到环境变量会返回空值if(name)return name;else return "none";
}//获取主机名字
const char* getHostname(void)
{const char* host=getenv("HOSTNAME");if(host)return host;else return "none";
}//获取工作目录
const char* getCwd(void)
{const char* cwd=getenv("PWD");if(cwd)return cwd;else return "none";
}//获取用户输入的命令
int getUserCommand(char* usercommand,int num)
{char* r=fgets(usercommand,num,stdin);if(r==NULL)return -1;usercommand[strlen(usercommand)-1]='\0';return strlen(usercommand);
}//分割字符串
int commandSplist(char* usercommand,char* argv[])
{int argc=0;argv[argc++]=strtok(usercommand,SEP);while(argv[argc++]=strtok(NULL,SEP));return 0;
}//执行命令
int execute(char* argv[])
{pid_t id=fork();if(id<0)return -1;else if(id==0){//childexecvp(argv[0],argv);//程序替换exit(1);//程序替换失败返回1}else{//fartherint status=0;//保存子进程退出时的退出码和退出信号pid_t rid=waitpid(id,&status,0);//阻塞等待if(rid>0)lastcode=WEXITSTATUS(status);//获取子进程退出时的退出码}return 0;
}//改变工作路径
void cd(const char* path)
{chdir(path);//改变工作路径//虽然路径改了,但是环境变量中PWD存储的工作路径并没有改变char temp[1024];getcwd(temp, sizeof(temp));sprintf(_cwd, "PWD=%s",temp);putenv(_cwd);//为什么这里putenv[temp]?因为temp是一个临时变量,putenv只是将temp这个指针放到环境变量体系中,当函数调用结束,指针就销毁了,这个工作路径的环境变量就访问不了了}//什么叫做内建命令:内建命令就是bash自己执行的,类似于自己内部的一个函数!
//1.是内建命令 0不是内建命令
//执行的是内建命令
int doBuildin(char* argv[])
{if(strcmp(argv[0],"cd")==0)//cd命令{char* path=NULL;if(argv[1]==NULL)path=".";elsepath=argv[1];cd(path);return 1;}else if(strcmp(argv[0],"export")==0)//export命令{if(argv[1]==NULL)return 1;strcpy(env_val,argv[1]);putenv(env_val);return 1;}else if(strcmp(argv[0],"echo")==0)//echo命令{char val_0=*argv[1];char* val=argv[1]+1;//argv[1]+1:例如$? 则argv[1]是$ argv[1]+1是?if(val_0=='$'&&strcmp(val,"?")==0)//我们定义?保存着最近一个进程的退出码{printf("%d\n",lastcode);lastcode=0;}else if(val_0=='$'){printf("%s\n",getenv(val));//打印环境}else//echo打印字符{printf("%s\n",argv[1]);}return 1;}else{//可以添加其他的内建命令}return 0;
}int main()
{while(1){char usercommand[SIZE];//存储用户输入的命令char* argv[NUM];//存储命令行参数//打印命令行提示符printf("[%s@%s %s]$",getUsername(),getHostname(),getCwd());//输入命令int n=getUserCommand(usercommand, sizeof(usercommand));if(n<=0)continue;//分割字符commandSplist(usercommand, argv);//判断是否是内建命令n=doBuildin(argv);if(n==1)continue;//执行命令execute(argv);}return 0;
}

 🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸 

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

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

相关文章

c语言编程题经典100例

以下是一些经典的C语言编程题目&#xff0c;这些题目可以帮助你提高C语言编程技能&#xff1a; 交换两个变量的值判断一个数是否为素数反转一个字符串计算一个数的阶乘计算一个数的平方计算一个数的立方计算一个数的对数计算一个数的倒数求一个数组中所有元素的和求一个数组中…

大语言模型领域的重要术语解释

前言 本人对人工智能非常感兴趣&#xff0c;目前是一名初学者&#xff0c;在研究大语言模型的一些内容。很多模型都是用英文提出的&#xff0c;其中也包括很多概念&#xff0c;有些概念的中文翻译和其想表达的意思不完全一样&#xff0c;所以在这里&#xff0c;想更加精准地帮…

vite vue3配置axios

准备 参考 安装axios yarn add axios中文官网 src下新建request文件夹&#xff0c;该文件下新建index.ts import axios from axios; import { ElMessage } from element-plus;// const errorCodeType function (code: number): string { // let errMessage: string 未知…

SAP的一些当说不说的常识

ABAP中的WDA与FRMbopf restful和odata postman软件 SAP中MM模块相关 SAP 物料 移动类型 https://www.cnblogs.com/rainysblog/p/4133259.html T移动类型文本含义一般用途T-code101GR 收货直接收货工单入库&#xff0c;购买成品入库MIGO/CO11N102用于PO冲销的收货冲销直接…

一阶低通滤波器(一阶巴特沃斯滤波器)

连续传递函数G(s) 离散传递函数G(z) 转换为差分方程形式 一阶巴特沃斯滤波器Filter Designer参数设计&#xff1a;参考之前的博客Matlab的Filter Designer工具设计二阶低通滤波器 设计采样频率100Hz&#xff0c;截止频率20Hz。 注意&#xff1a;设计参数使用在离散系统中&…

【性能测试】稳定性/并发压力测试的TPS计算+5W并发场景设计...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、稳定性测试TPS…

AI生成技术威胁版权保护,水印技术和法律完善是关键/安圭拉小岛以.ai域名注册赚得3000万美元 |魔法半周报

我有魔法✨为你劈开信息大海❗ 高效获取AIGC的热门事件&#x1f525;&#xff0c;更新AIGC的最新动态&#xff0c;生成相应的魔法简报&#xff0c;节省阅读时间&#x1f47b; &#x1f525;资讯预览 AI生成技术威胁版权保护&#xff0c;水印技术和法律完善是关键 Sam Altman对…

软件外包开发的验收流程

软件外包开发的验收流程是确保项目符合预期标准并满足客户需求的关键步骤。以下是一个通用的软件外包开发验收流程&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.明确验收标准&#xff1a; 在项目…

jmeter接口自动化部署jenkins教程详解

首先&#xff0c;保证本地安装并部署了jenkins&#xff0c;jmeter&#xff0c;xslproc 我搭建的自动化测试框架是jmeterjenkinsxslproc 注意&#xff1a;原理是&#xff0c;jmeter自生成的报告jtl文件&#xff0c;通过xslproc工具&#xff0c;再结合jmeter自带的模板修改&…

【C语言】条件变量(pthread_cond_t)

一、概述 条件变量(pthread_cond_t)是POSIX线程&#xff08;也称为pthread&#xff09;库中用于线程同步的一种机制。在多线程程序中&#xff0c;条件变量通常与互斥锁(pthread_mutex_t)一起使用&#xff0c;以防止并发问题&#xff0c;如竞态条件和死锁。 二、条件变量(pthre…

渲染器之挂载与更新

讲解渲染器的核心功能&#xff1a;挂载与更新。 1、挂载子节点和元素的属性 当 vnode.children 的值是字符串类型时&#xff0c;会把它设置为元素的文本内容。一个元素除了具有文本子节点外&#xff0c;还可以包含其他元素子节点&#xff0c;并且子节点可以是很多个。为了描述…

IonQ、Rigetti、D-Wave公布2023年第三季度财报!

近期&#xff0c;量子计算公司Rigetti、IonQ和D-Wave均公布了各自在2023年第三季度的盈利收益。 这三家公司在近期均实现了收入增长&#xff0c;并助力客户实现相应的业务增长。然而&#xff0c;在追求实现量子霸权和超越经典硅基计算机系统的同时&#xff0c;这些公司仍面临着…

ECharts零基础使用思路 图表案例网站推荐

1、用npm安装echarts npm i echarts -S 2、引入 &#xff08;1&#xff09;可以在mian.js里全局引入 import echarts from ‘echarts’ Vue.prototype.$echarts echarts 将echarts挂载在Vue原型上 用时直接this.$echarts即可 &#xff08;2&#xff09;也可以在组件中按需引入…

安卓毕业设计:基于安卓android微信小程序的在线医生答疑系统

项目介绍 在线医生答疑开发使系统能够更加方便快捷&#xff0c;同时也促使在线医生答疑变的更加系统化、有序化。系统界面较友好&#xff0c;易于操作。具体在系统设计上&#xff0c;客户端使用微信开发者&#xff0c;后台也使用java技术在动态页面上进行了设计&#xff0c;My…

音视频项目—基于FFmpeg和SDL的音视频播放器解析(十五)

介绍 在本系列&#xff0c;我打算花大篇幅讲解我的 gitee 项目音视频播放器&#xff0c;在这个项目&#xff0c;您可以学到音视频解封装&#xff0c;解码&#xff0c;SDL渲染相关的知识。您对源代码感兴趣的话&#xff0c;请查看基于FFmpeg和SDL的音视频播放器 如果您不理解本…

windows系统 phpstudy 安装 imagick 扩展

其他博客 https://blog.csdn.net/json_ligege/article/details/130227725 1. 下载 imagemagick.org 注意版本对应 官网 https://imagemagick.org/script/download.php#windows github地址 //老版本需要自己编译 https://github.com/ImageMagick/ImageMagick/releases 其他地址…

Linux C 基于tcp多线程在线聊天室

多线程在线聊天室 概述客户端服务端 概述 客户端实现了判单用户登录结果、防止单回车字符发送、保存和显示历史聊天记录&#xff08;仅自己&#xff09;、退出聊天室功能。   服务端实现了验证用户是否已经存在&#xff08;支持最大64用户连接&#xff09;支持广播用户进入退…

自定义类型转换函数operator MyInt()

/*** * 结论&#xff1a;对pass-by-value传参的常规调用&#xff0c;会用实参拷贝构造形参&#xff0c;实参与形参相互无影响&#xff1b; * 当对实参调用类型转换函数(返回形参类型)&#xff0c;编译器会优化代码使类型转换函数返回值直接构造在调用作用域的接受对象上 */ …

AR眼镜方案—单目光波导AR智能眼镜

光波导技术是一项具有前沿意义的技术&#xff0c;它能够将光线反射180度&#xff0c;使得眼镜框架内置的MicroLED屏幕的图像通过多次反射与扩散后准确地传递到人眼中。采用MicroLED显示技术的AR智能眼镜不仅体积显著缩小&#xff0c;屏幕只有0.68英寸大小&#xff0c;并且还能够…

crontab

crontab 详细用法 定时任务_crontab每周六凌晨一点重启-CSDN博客 使用 Crontab 设置开机启动 Python 脚本_crontab开机启动脚本-CSDN博客 编写一个 shell 脚本 $ cat test.sh #!/bin/bashpython3 main.py > ~/output-20230901.txtubuntu环境下开启定时任务crontab_ubuntu…