当前位置: 首页 > news >正文

Linux——自写一个简易的shell

目录

前言

一、打印提示信息

二、分割字符串

三、替换程序


前言

之前学习了很多进程相关的知识,包括环境变量、进程的创建与退出、进程等待、进程替换。现在可以用所学的作一个小总结,手撕一个shell解释器,大致的思路是先通过环境变量获取相关信息,再通过fork创建子进程并进行程序替换,bash的命令。

一、打印提示信息

当我们链接上虚拟机,就会有这一行输出到屏幕上,告诉我们可以开始输入命令了。首先我们得把提示写出来。

环境变量中有用户名、主机号、当前目录等信息,我们可以通过 getenv 获取相关信息进行打印。

同时,我们输入命令会有很多空格存在,比如 ls -a -l。因此不能用scanf获取输入信息,可以用fgets,第三个参数为stdin(标准输入)。最后输入完毕后会输入回车换行,我们将最后一个字符设置为  '\0'  代表字符串的结束,同时也避免了换行。

#inlcude<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#define NUM 1024char* getUsername()
{char* env = getenv("USER");if(env) return env;return NULL;
}char* getHostname()
{char* env = getenv("HOSTNAME");if(env) return env;return NULL;
}char* getPwd()
{char* env = getenv("PWD");if(env) return env;                                            return NULL;
}int main()
{char command[NUM];printf("[%s@%s %s]$ ",getUsername(),getHostname(),getPwd());//打印fgets(command,NUM,stdin);  //输入完成后还会输入回车,导致换行command[strlen(command)-1] = '\0'; printf("%s",command);  // 打印看看是否获取到了完整的字符串
}

运行结果如下,获取了完整了字符串。

二、分割字符串

分割字符串C语言可以用strtok函数,他第一个参数为需要分割的字符串,第二个参数是按什么字符进行分割。如果想继续往后分割同一字符传,后续需要将第一个参数设置为NULL。

分割成功返回值为分割出来的字符串,如果分割失败,返回0。

我们先分割一次字符串,放到数组argv里,后面使用while循环一直进行分割,由于分割失败返回0,自然而然就退出了。下面是打印代码,看看结果是否正确。

成功分割。

三、替换程序

fork出子进程,然后使用execvp进行程序替换,第一个参数为argv[0],比如你输入ls -a -l,他会自己去path路径里面查找 ls 是否存在,第二个参数为agrv,整个数组放进去,是命令行参数。这里写简单一点,没有处理等待失败的情况。

成功进行替换。 

最后给他套上循环,一个建议的shell就做好了。我们写的比较简单,有很多bug,功能还不算完善,但是勉强也算够用。

附上总代码 

  #include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<string.h>#define NUM 1024#define SIZE 64char* getUsername(){char* env = getenv("USER");if(env) return env;return NULL;}char* getHostname(){char* env = getenv("HOSTNAME");if(env) return env;return NULL;}char* getPwd(){char* env = getenv("PWD");if(env) return env;return NULL;}int main(){while(1){char command[NUM];char* argv[SIZE];int argc = 0;printf("[%s@%s %s]$ ",getUsername(),getHostname(),getPwd());//打印fgets(command,NUM,stdin);  //输入完成后还会输入回车,导致换行command[strlen(command)-1] = '\0';argv[argc++] = strtok(command," ");while(argv[argc++] = strtok(NULL, " "));pid_t id = fork();if(id == 0){//childexecvp(argv[0],argv);exit(1);}else{pid_t rid = waitpid(id,NULL,0);if(rid>0) printf("等待成功\n");}}}

这里完善了一下代码,添加了重定向,在大标题“四”。

相关文章:

Linux——自写一个简易的shell

目录 前言 一、打印提示信息 二、分割字符串 三、替换程序 前言 之前学习了很多进程相关的知识&#xff0c;包括环境变量、进程的创建与退出、进程等待、进程替换。现在可以用所学的作一个小总结&#xff0c;手撕一个shell解释器&#xff0c;大致的思路是先通过环境变量获…...

【操作系统学习笔记】处理器管理1.3

【操作系统学习笔记】处理器管理1.3 参考书籍: 王道考研 视频地址: Bilibili 进程控制 进程控制的主要功能是对系统中的所有进程实施有效的管理&#xff0c;它具有创建新进程、撤销已有进程、实现进程状态转换的功能。简而言之&#xff0c;进程控制就是要实现进程的状态转换…...

AndroidUI--setContentView

我们的Activity通常继承自Activity或者AppCompatActivity&#xff0c;这两个setContentView流程是不同的 一、继承自Activity 1、Activity.setContentView Activity中setContentVIew调用了getWindow().setContentView(view, params); getWindow返回的是mWindow&#xff0c;mWi…...

编程笔记 Golang基础 047 mysql数据库连接与操作

编程笔记 Golang基础 047 mysql数据库连接与操作 一、连接与操作1. 安装MySQL驱动2. 导入驱动包3. 连接数据库4. 执行SQL查询和操作5. 使用连接池6. 处理事务 二、连接字符串三、应用示例四、比较 MySQL凭借其开源、高效、稳定、灵活、安全以及广泛的社区支持等诸多优势&#x…...

.jsonl 格式文件的解释

根据 CHATGPT .jsonl 文件格式是一种文本文件格式&#xff0c;通常用于存储每行一个JSON对象的数据。.jsonl 文件的每一行都是一个独立的JSON对象&#xff0c;这些对象之间没有任何分隔符。 以下是一个示例.jsonl文件的内容&#xff1a; {"name": "John"…...

nodejs web服务器 -- 搭建开发环境

一、配置目录结构 1、使用npm生成package.json&#xff0c;我创建了一个nodejs_network 文件夹&#xff0c;cd到这个文件夹下&#xff0c;执行&#xff1a; npm init -y 其中-y的含义是yes的意思&#xff0c;在init的时候省去了敲回车的步骤&#xff0c;如此就生成了默认的pac…...

laravel-admin 头部添加操作

新建html 样式及js namespace App\Admin\Extensions\Nav;class Links {public function __toString(){return <<<HTML<li><a href"" οnclick"js_method();return false;"><i class"fa fa-floppy-o"></i><s…...

mysql笔记:10. 日志

文章目录 一、日志概述二、错误日志1. 启动2. 查看3. 删除 三、二进制日志1. 启动2. 查看3. 删除 四、通用查询日志1. 启动2. 查看3. 删除 五、慢查询日志1. 启动2. 查看3. 删除 日志是MySQL数据库的重要组成部分&#xff0c;日志文件中记录着MySQL数据库运行期间发生的变化。M…...

代码随想录刷题笔记-Day32

1. 最大子序和 53. 最大子数组和https://leetcode.cn/problems/maximum-subarray/ 给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。 子数组&#xff1a;是数组中的一个连续…...

指针的学习5

目录 sizeof和strlen的区别 sizeof strlen 数组和指针笔试题解析 一维数组 字符数组 二维数组 指针运算笔试题解析 题目1&#xff1a; 题目2&#xff1a; 题目3&#xff1a; 题目4&#xff1a; 题目5&#xff1a; 题目6&#xff1a; 题目7&#xff1a; sizeof和…...

Dynamo——常用几何形体的创建与编辑(二)

上一次&#xff0c;我们简单整理了一些创建几何形体的节点用法&#xff0c;今天我们接着整理一些&#xff0c;几何形体的编辑方法。 一、坐标点的平移复制 [Point.Add] 使用节点 “Vector.ByCoordinates” 生成一个向量&#xff0c;将该向量连接到 “Point.Add” 节点的输入端 …...

uniapp富文本编辑-editor-vue2-vue3-wangeditor

前言 不管vue2还是vue3&#xff0c;都推荐官方的editor组件, 官方手册 https://uniapp.dcloud.net.cn/component/editor.html除了“微信小程序”&#xff0c;其他小程序想要使用editor组件实现富文本编辑&#xff0c;很难 ​​​​​​​第三方组件wangeditor在vue2&#xff0…...

【java】22:try-catch 异常处理

try-catch 方式处理异常说明 public static void main(String[] args) { int num1 10; int num2 0; try { int res num1 / num2; } catch (Exception e) { System.out.println(e.getMessage()); } } 注意事项 1)如果异常发生了&#xff0c;则异常发生后面的代码不会执行&…...

【C语言】linux内核ip_local_out函数

一、讲解 这个函数 __ip_local_out 是 Linux 内核网络子系统中的函数&#xff0c;部分与本地出口的 IPv4 数据包发送相关。下面讲解这段代码的每一部分&#xff1a; 1. 函数声明 int __ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb)&#xff1a; -…...

动态规划6,最大数组和,环形子数组最大和,乘积最大子数组

最大子数组和 思路&#xff1a; 1.经验题目要求 dp[i]表示&#xff1a;以 i 位置为结尾的所有子数组中的最大和 2.状态转移方程 按长度来划分&#xff0c;如果长度为1&#xff0c;那么dp[i] nums[i]; 如果长度大于1&#xff0c;那么当前位置的最大和就为 i-1 位置最大和 …...

js 清空数组的方法

1、直接赋值空数组 let array [1, 2, 3, 4, 5]; array []; 这种方法并不推荐&#xff0c;如下图所示&#xff1a; 虽然a数组确实变为了空数组&#xff0c;但这种方法只是修改了a的指向&#xff0c;把a指向一个新的空数组&#xff0c;然而[1,2,3,4,5]这个数组并没有被清除&a…...

QT中使用QProcess执行命令,实时获取数据,例如进度条

前言 因为之前写了一个接收和发送文件的脚本&#xff0c;然后又需要获取进度&#xff0c;同步到进度条中。 效果&#xff1a; 使用正则匹配&#xff0c;获取命令行命令中的以下数据&#xff0c;然后同步到进度条 源码demo&#xff1a; 非完整代码&#xff1a; #include <Q…...

绘图设计:用Draw.io绘制图形技巧大全(含统一建模语言UML模板)

一、常见UML模板 1.流程图 2.用例图 include是包含关系&#xff0c;extend是扩展关系 简而言之&#xff0c;include是子集指向父集&#xff1b;而extend是扩展用例指向基础用例&#xff08;基础用例可以理解为系统核心功能&#xff0c;扩展用例是可选的&#xff0c;不是必须…...

被唤醒的“第二十条”深入人心

近来张艺谋执导的电影《第二十条》&#xff0c;因为它与正在召开中的全国两会所发布的《最高人民法院工作报告》联系相当紧密&#xff0c;加之可免费收看&#xff0c;网民便相互转告&#xff0c;于是此信息条目立即冲上了网络热搜榜&#xff0c;观者如潮。因为最高人民法院工作…...

PHPInfo()信息泄漏原理以及修复方法

漏洞名称&#xff1a;PHPInfo信息泄漏、phpinfo()函数信息泄漏 漏洞描述&#xff1a; phpinfo()函数返回的信息中包含了服务器的配置信息&#xff0c;包括&#xff1a; 1&#xff09;PHP编译选项以及文件扩展名的相关信息&#xff1b; 2&#xff09;php的版本信息 3&#…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

React---day11

14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store&#xff1a; 我们在使用异步的时候理应是要使用中间件的&#xff0c;但是configureStore 已经自动集成了 redux-thunk&#xff0c;注意action里面要返回函数 import { configureS…...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库&#xff0c;分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷&#xff0c;但是文件存放起来数据比较冗余&#xff0c;用二进制能够更好管理咱们M…...

《信号与系统》第 6 章 信号与系统的时域和频域特性

目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …...

ArcPy扩展模块的使用(3)

管理工程项目 arcpy.mp模块允许用户管理布局、地图、报表、文件夹连接、视图等工程项目。例如&#xff0c;可以更新、修复或替换图层数据源&#xff0c;修改图层的符号系统&#xff0c;甚至自动在线执行共享要托管在组织中的工程项。 以下代码展示了如何更新图层的数据源&…...

python读取SQLite表个并生成pdf文件

代码用于创建含50列的SQLite数据库并插入500行随机浮点数据&#xff0c;随后读取数据&#xff0c;通过ReportLab生成横向PDF表格&#xff0c;包含格式化&#xff08;两位小数&#xff09;及表头、网格线等美观样式。 # 导入所需库 import sqlite3 # 用于操作…...