简易的shell实现
创始人
2024-03-09 05:19:52

这篇文章的内容主要是利用进程的创建,等待,终止,替换。这些知识来实现一个自己的简易shell
在这里插入图片描述

文章目录

  • 1. 大致思路
  • 2. 基本实现
  • 3. 额外拓展
    • 3.1 让文件带上颜色
    • 3.2 内建命令
    • 3.3 添加环境变量

1. 大致思路

我们用了这么长的shell,它的大概过程是这样:
在这里插入图片描述
其实就是我们在不断的输入一个程序,然后执行它。因为这个shell是不断可以执行程序,所以应该是shell创建一个子进程来完成我们输入的命令。如下图所示:
在这里插入图片描述
所以要写一个shell,需要循环以下过程:
1. 获取命令行
2. 解析命令行
3. 建立一个子进程(fork)
4. 替换子进程(execvp)
5. 父进程等待子进程退出(wait)

2. 基本实现

首先,shell就是一个死循环,当我们输入一个命令结束后,他就会开始下一个命令:
在这里插入图片描述
第二步,我们要提示一下用户:
在这里插入图片描述
这里我们为什么要这样来刷新,因为我们\n它会换行,我们输入命令一般是在提示符后面输入,而不是在下一行输入。
在这里插入图片描述
我们定义一个数组来存放你的字符串,然后把输入的字符串存进数组里:
在这里插入图片描述
这里我们一定要把回车清理,因为回车也是一个字符(\n)。我们这里用的fgets函数,可以看一下它的语法:
在这里插入图片描述
第三步,我们需要把输入的字符串按空格分割。因为在程序替换时,它是一个一个分开传的,我们可以把分割后的字符串放进一个数组里。
在这里插入图片描述

在这里插入图片描述
= 是故意这么写的,strtok 截取成功,返回字符串其实地址,截取失败,返回NULL。
这个strtok函数不理解的可以看这个文章:字符函数和字符串函数
第四步,我们创建一个子进程去进行程序替换:
在这里插入图片描述
我们来看一下运行结果:
在这里插入图片描述
我们可以看到大致是没有问题的。

3. 额外拓展

3.1 让文件带上颜色

我们平时用的shell,像可执行程序是绿色的,目录是蓝色的。那我们该如何实现呢?
首先,有一个alias的命令,它的意思是别名。
在这里插入图片描述
我们可以看到:myls和ls -a -l执行的一样的,但本质还是ls。那么我们可以看一下系统里的ls。
在这里插入图片描述
这个alias的意思是别名。ls本身是不带颜色的,但是加上一些其它选项。所以,我们自己写的时候,子进程程序替换找的是系统的ls,没有加上后面的选项。
在这里插入图片描述
所以遇到ls命令时,可以在下标为1的数组里加上这个选项。

3.2 内建命令

在这里插入图片描述
这个现象,我们可以看出我们cd过后,路径没有变化这是为什么。
在这里插入图片描述
从这里可以看出,我们用的cd可能不是/usr/bin目录下的。那这个cd是什么呢?
如果直接exec*执行cd命令,最多只是让子进程进行路径切换,但子进程是一运行就完毕的进程。但是在shell中,我们更希望父进程(shell本身)进行路径切换,因为父进程路径发生变化,后面的子进程也会继承父进程的路径

如果有些行为,是必须让父进程shell执行的,不想让子进程执行的,绝对不能创建子进程。只能父进程自己实现对应的代码,由shell自己执行的命令,我们称之为内建(bind-in)命令。相当于shell内部的一个函数

我们先看一下这个函数chdir:
在这里插入图片描述
这个系统调用函数意思是:用于改变当前工作目录,其参数为path 目标目录,可以是绝对目录或相对目录。
在这里插入图片描述
在这里插入图片描述
command_arge[1]里面存的就是目标路径。我们看一下运行结果:
在这里插入图片描述
这样就完美的解决了。那么有哪些内建命令呢?cd,export,echo这些都是。

3.3 添加环境变量

在这里插入图片描述
我们来看一下这样的运行结果:
在这里插入图片描述
所有的程序替换,如果我们不传环境变量,那么它会默认继承父进程的环境变量列表

在前面,我们使用带e的exec函数时。自己传环境变量,它会覆盖系统的环境变量,那么我们该如果添加式的传环境变量,而不是覆盖式的呢
在这里插入图片描述
在这里插入图片描述
从这个结果可以看到,我们在myshell里export没有办法添加,我们也不能使用environ指针去改变环境变量数组。我们可以使用一个putenv的函数:把字符串加到当前环境中
在这里插入图片描述
我们先来演示一下:
在这里插入图片描述
在这里插入图片描述
我们这样来做看能不能成功:
在这里插入图片描述
我们可以看到还是没有成功。原因是:
在这里插入图片描述
每次循环时,它会重新初始化数组。这样我们写的环境变量的内容下一次就没了,所以我们需要自己保存一下环境变量内容。
在这里插入图片描述
这里的env_buffer如果我们不想消失可以用动态开辟的,如果我们想存多个环境变量可以用二维数组。
在这里插入图片描述
此时我们再测试一下:
在这里插入图片描述
我们看到成功添加了环境变量。

总结
1. 环境变量的数据,保存在进程的上下文中。
2. 环境变量会被子进程继承下去,所以会有全局属性。
3. 当我们进行程序替换的时候,当前进程的环境变量非但不会被替换,而且会继承父进程的

在这里插入图片描述

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...