简易的shell实现

news2024/11/25 6:56:45

这篇文章的内容主要是利用进程的创建,等待,终止,替换。这些知识来实现一个自己的简易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. 当我们进行程序替换的时候,当前进程的环境变量非但不会被替换,而且会继承父进程的

在这里插入图片描述

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

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

相关文章

DolphinDB 四大因子库合集

目前市场上常见两种类型的因子库:技术分析类和基本面类。 常用的技术分析因子库包括 TA-Lib、WorldQuant 的101 alpha、通达信的 mytt、国泰君安的191等。 基本面因子方面,美联储高级经济学家 Andrew Chen 及科隆大学教授 Tom Zimmermann 详细整理总结…

Hadoop原理与技术——Linus命令行基本操作

一、实验目的 Hadoop运行在Linux系统上,因此,需要学习实践一些常用的Linux命令。本实验旨在熟悉常用的Linux操作,为顺利开展后续其他实验奠定基础。 二、实验环境 Windows 10 VMware Workstation Pro虚拟机 Hadoop环境 Jdk1.8 三、实验内…

IP-Guard如何判断Windows客户端是否安装成功?

1.在电脑本地打开services.msc 服务页面,找有没有windows helper service服务,该服务的可执行文件的路径中的进程是winrdgv3.exe是客户端进程。 2.cmd输入netstat -an|find "823",从输出的内容上判断是否连接上服务器连; 客户端开放…

Linux基础知识与实操-篇八:定期任务执行与进程任务处理

文章目录例行工作安排单一工作安排循环执行的任务注意事项唤醒停机期间的任务进程任务处理任务管理job control后台执行进程管理进程的执行顺序系统资源查看特殊文件与进程最后例行工作安排 类似于定时任务、系统安排的任务提醒等 一般在任务中,有两个类型&#x…

MR小区搜索(六)cell reselection

微信同步更新欢迎关注同名modem协议笔记 小区选择和小区重选都是idle态行为,小区重选无非是为了让UE驻留在信号状况最好的小区上,以便之后在connected mode获得更好的体验,小区重选的目标小区也要满足S准则,下面就来具体看下小区…

19c pdb克隆单机到rac,日志出现:WARNING报警处理

打开pdb后,警告日志出现 Violations: Type: 2, Count: 1 *************************************************************** WARNING: Pluggable Database PDB3 with pdb id - 3 is altered with errors or warnings. Please look into PDB_PLUG_IN_VIOLATIONS vie…

运算符-12-多学一招原码反码补码,隐式和强制转换,位运算

下面来解释这些东西是怎么来的 原码 例如: 最左边的叫做符号位,0 为正,1 为负,后面的才是具体的数值 在计算机中,一个 0 或者 1 所占的空间叫 bit 中文名叫比特位,八个 bit 就称为一个字节,字…

Java+Swing学生信息管理系统(含源码+论文+答辩PPT等)

该项目采用技术:JDBCAWTSwing集合面向对象编程等相关技术,项目含有源码、文档、配套开发软件、软件安装教程、项目发布教程等 项目功能介绍: 系统管理:用户登录、退出、注册 学校管理:设置学生学校以及联系方式等信息 …

C语言——矩阵转置

矩阵转置的原理&#xff1a;行元素变成列元素&#xff0c;列元素变成行元素 例如&#xff1a; 矩阵转置代码 #include<stdio.h> #include<malloc.h> #include<stdlib.h> #include<math.h>//矩阵转置 double** Matrix_T(double** arr) {if(arrNULL)e…

Linux服务器配置与管理(基于Centos7.2)任务目标(六)

文章目录一、实验目的&#xff1a;二、实验内容及基本要求&#xff1a;三、实训步骤一、实验目的&#xff1a; ●了解Shell脚本的概念和执行方法&#xff1b;能熟编写Shell脚本来管理系统 二、实验内容及基本要求&#xff1a; 1、使用脚本批量创建用户 2、使用脚本批量删除用…

【895. 最大频率栈】

来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 描述&#xff1a; 设计一个类似堆栈的数据结构&#xff0c;将元素推入堆栈&#xff0c;并从堆栈中弹出出现频率最高的元素。 实现 FreqStack 类: FreqStack() 构造一个空的堆栈。void push(int val) 将一个整数 val …

MySQL索引的底层数据结构原理剖析(二叉树、 红黑树、Hash、B-Tree、B+Tree)

一. 前言 1. 说明 我们平时所说的&#xff1a;聚集索引(主键索引)&#xff0c;次要索引&#xff0c;覆盖索引&#xff0c;复合索引&#xff0c;前缀索引&#xff0c;唯一索引在MySQL5.7和 8.0版本默认都是使用BTree索引&#xff0c;除此之外还有 Hash索引。至于MySQL5.7之前版…

Go-Excelize API源码阅读(三十八)——SetCellStyle

Go-Excelize API源码阅读&#xff08;三十八&#xff09;——SetCellStyle 开源摘星计划&#xff08;WeOpen Star&#xff09; 是由腾源会 2022 年推出的全新项目&#xff0c;旨在为开源人提供成长激励&#xff0c;为开源项目提供成长支持&#xff0c;助力开发者更好地了解开源…

智慧城市运营中心建设方案(SCOC)智慧城市的心脏

一、大数据&#xff1a;智慧城市的基础与引擎 中国每天正以消失100个村庄的速度快速步入城镇化&#xff0c;未来10年内将有5亿以上的人涌入城市。这无疑会给城市的建设带来巨大的压力&#xff0c;城市资源有限&#xff0c;规模不可能无限扩张&#xff0c;城市在就业、教育、住房…

【数据库基础】数据库介绍和三大范式

数据库简介&#x1f33e;第一章 数据库简介&#x1f54a;️1.1 简介&#x1f54a;️1.2 常见数据库管理系统&#x1f54a;️1.3 三大范式&#xff08;规范&#xff09;&#x1f375;第一范式&#xff1a;&#x1f375;第二范式:&#x1f375;第三范式&#x1f33e;第一章 数据库…

实用调试技巧

个人主页&#xff1a;平行线也会相交 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 目录什么是bug&#xff1f;调试是什么&#xff1f;有多重要&#xff1f;调试是什么调试的基本步骤debug和release的介绍windows环境调试介绍快捷键调试的时候查看程序当前…

基于51单片机六车道智能交通灯设计(仿真+源程序+PCB+论文)

资料编号&#xff1a;204 功能介绍&#xff1a;&#xff08;全套毕设资料齐全&#xff09; 本设计的交通灯以十字路口为模型&#xff0c;在实现基本的功能前提下增加了时间及温度的液晶显示。从而还增加了路口高峰期的智能化人工管理机制。 实际生活中交通信号灯的规则千变万…

C++ 大作业/课程设计 小型公司工资管理软件

小型公司工资管理软件一、实验目的二、实验要求三、项目分工四、软件设计0.效果图&#xff1a;1.类的继承关系2.类的设计3.程序运行流程4.异常处理1. 用户输入异常2.文件操作异常五、程序代码一、实验目的 熟悉面向对象程序设计思想&#xff0c;掌握类、类的派生、静态成员、多…

JVM之运行时数据区 方法区

JVM方法区概述设置方法区的大小参数如何解决这些OOM内部结构补充non-final的类变量全局变量&#xff1a;static final常量池运行时常量池方法区的演进StringTable为什么要调整&#xff1f;方法区垃圾回收总览概述 《java虚拟机规范》中明确说明&#xff1a;“尽管所有的方法区…

Tableau可视化项目

文章目录Tableau可视化项目一、数据来源二、项目介绍1.项目目的2.架构三、数据可视化1.人口1.1 总人口、城镇人口、乡村人口1.2 人口出生率、死亡率、自然增长率1.3 人口年龄结构1.4 男女比例2.居民生活水平2.1 医疗情况2.2 恩格尔系数2.3 人均消费支出3.经济3.1 能源弹性系数3…