自主Shell命令行解释器

Shell的本质:

首先要明确一点:shell是我们未来所以进程的父进程。

shell想要执行命令,就需要从命令行中获取我们输入的字符串,shell会不断获取,所以其实,shell的本质其实是一个死循环!

并且,如今我们使用的大部分软件都是一个死循环,就比如说:你在看我这篇博客时,你不点击右上角的'x',这个软件就不会自动退出,而是一直维持当前循环。

1.打印命令行:

此时,我们的shell打印除了命令行之后,就因该从键盘中获取我们的输入

2.获取输入信息:

fgets():

fgets()可以从指定的文件(stream)中,获取到字符串s,该字符串的长度为参数size

封装函数:

3.解析字符串

我们需要将命令行字符串从"ls -a -l" 解析为 "ls" "-a" "-l"

最终目的:

切割方法:strtok

strtok的使用方法:

命令行解析命令:bash来解析命令行,其实和我们手搓的解析类似,都需要将一个字符串分割成一个一个小的命令,制成一个命令行参数表

4.执行命令

在第三步中,我们就已经将命令一个一个解析到了我们的命令行参数表了,所以想要执行命令,就只用一个一个执行命令行参数表中的内容即可。

最终,我们就完成了我们自己的shell,通过完成自主shell的过程,我们可以更清晰地了解到:shell其实就是一个死循环的过程,其命令运行的本质也是进程替换!

不过,我们这个shell对于所有的命令,都是让子进程去执行的,那么是否有一些指令是只能由父进程来执行的呢?

cd ..:路径切换指令,该指令切换的是父进程bash的路径,再经由bash传递给子进程,这样才能改变每个进程的路径,才能真正完成路劲切换。

5.内建命令:

原因是因为:在我们获取主机名时,使用的是:getenv("HOSTNAME")直接使用的是环境变量,该环境变量是从父进程的环境变量中拿出来的,而当我们更改路径后,操作系统并不会自动更改环境变量中的路径。

我们使用chdir是用户层面的数据进行更改,并不是操作系统的数据进行了更改,所以,我们需要让bash自己更改环境变量!

法一:系统调用

那如果说一定要从环境变量中获取工作路径呢?

法二:环境变量

既然需要直接改变系统的环境变量,首先就要找到我们的路径:

此时我们就明确了目标:就是要将环境变量中的PWD直接进行修改!!!

snprintf()

该函数其实和printf类似,不过可以由我们指定打印的目标对象。

最终,我们就完成对环境变量的修改,也就可以直接从环境变量中获取信息!

不过,我们并没有给myshell写环境变量表啊?那么他的环境变量表从何而来呢?

答案是:当我们执行myshell.exe可执行文件时,也就创建了一个shell的bash的子进程,我们成shell的bash为父bash,而myshell的bash由于父子进程的继承性,也就继承了父bash的环境变量表,而当我们对myshell的环境变量表进行写入时,也就自动触发了"写实拷贝"此时父子进程的环境变量表也就彻底分开了!此时,bash也就拥有了不同于父bash的环境变量表!!!

6.myshll进一步优化

一、路径显示

我们只需使用从尾到头查找字符串,找到 '\' 时就对该字符串进行截取即可。

二、退出码

所以,接下来我们的目标就是让echo $?得到上一条命令的退出码!

首先,我们要明确一点,父进程是可以拿到子进程的退出码的!

分析原理,定义全局

退出码默认为0

status

原理回溯

由于更新的延迟性,下一条指令结束之前,lastcode中保存的就是上一条指令结束的退出码

最终实现

通过上述操做,我们就可以完成echo $?得到上一条指令的退出码!

然而,我们的实现是有局限性的,如果面临echo PATH等想要得到环境变量中的内容,myshell就只能对echo命令进行回显,而不会打印真正的环境变量,这也就意味着我们需要做更多的关键词识别!!!

总结:

通过这篇文章,我们可以更好地理解shell底层运行的原理!

源代码:

自主shell · e98c943 · wgl520666/Linux学习仓库 - Gitee.com

相关推荐
熙丫 133814823862 小时前
以新国标开启网络安全保障新视野——CISAW安全运维认证助力专业人才培养
运维·安全·web安全
Crazy________2 小时前
Kubernetes探针实战和生命周期
linux·服务器·网络·kubernetes
xuyuan19982 小时前
超越Selenium:自动化测试框架Cypress在现代前端测试中的卓越实践(windows版本)环境搭建
前端·windows·cypress
时空自由民.2 小时前
SSH 免密连接服务器
运维·服务器·ssh
.小小陈.4 小时前
Linux高频基础实用指南:从文件操作到日志
linux·运维·服务器
Java.熵减码农10 小时前
解决Linux修改环境变量后导致登录循环进不去系统的问题
linux·运维·服务器
明天好,会的10 小时前
分形生成实验(五):人机协同破局--30万token揭示Actix-web状态管理的微妙边界
运维·服务器·前端
天骄t10 小时前
嵌入式系统与51单片机核心原理
linux·单片机·51单片机