Linux 原来实现一个shell这么容易!(史上最简单详细)
shell实际上是一个命令的解释程序,是一个用户与系统内核沟通的桥梁。那我们能不能通过代码自己实现一个shell呢?当然可以,看完这篇博文,我相信你会受益匪浅!
通常情况下,我们linux系统默认的shell是bash
,下面是bash
的工作流程:
总结有以下四步骤:
- 等待用户标准输入
- 对输入的信息进行读取和解析,得到命令名称及命令运行所需要的参数
- 创建子进程,在子进程中进行程序替换,让子进程去运行读取解析后的指定命令
- 父进程等待子进程的退出
1、等待用户标准输入
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>int main(){//1、等待标准输入char buf[1024] = { 0 };fgets(buf, 1023, stdin);//将输入的数据放在buf中buf[strlen(buf) - 1] = '\0';//将最后一个换行取消printf("buf:[%s]\n", buf);//2、对输入数据进行读取解析//3、创建子进程,在子进程中进行程序替换//4、父进程进程等待return 0;}
运行结果:
我们已经获取到了用户输入的命令参数,并且存到了字符数组buf中
2、读取解析buf中的命令
//2、对输入数据进行读取解析char *argv[32] = {NULL};int argc = 0;char *ptr = buf;// [ ls -a -l ]while (*ptr != '\0'){ if (*ptr != ' '){argv[argc++] = ptr;while (*ptr != ' ' && *ptr != '\0'){ptr++;}*ptr = '\0';}ptr++;}argv[argc] = NULL;//最后一个参数位置的下一个位置置NULL
从buf存到指针数组argv中
3、创建子进程,在子进程中进行程序替换
//3、创建子进程,在子进程中进行程序替换pid_t pid = fork();if (pid == 0)//子进程{execvp(argv[0],argv);//程序替换成功就不会执行下面代码,而去执行新的程序perror("execvp error");//程序替换失败时会打印上一次系统调用接口使用的错误原因exit(0);}
4、父进程进行进程等待
wait(NULL);
完整代码:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>int main()
{while (1){printf("[WhiteShirtI@shell workspace]$ ");fflush(stdout);//刷新标准输出缓冲区//1、等待标准输入char buf[1023] = {0};fgets(buf, 1023, stdin); //将输入存放到buf中buf[strlen(buf) - 1] = '\0';//将最后一个换行取消//2、对输入数据进行读取和解析char *argv[32] = { NULL };int argc = 0;char *ptr = buf;//遍历命令和参数,不为空就继续遍历while (*ptr != '\0'){//遇到命令或者参数if (*ptr != ' '){//让agv第argc的位置放ptr这个指针argv[argc++] = ptr;while (*ptr != ' ' && *ptr != '\0'){ptr++;}//一个命令或参数的结束标志*ptr = '\0';}ptr++;}argv[argc] = NULL;//最后一个参数位置的下一个位置置为NULL//3、创建子进程,在子进程中进行程序替换pid_t pid = fork();if (pid == 0) //子进程{//execvp(命令名称, 命令参数)execvp(argv[0], argv);//程序替换成功不会执行下面代码perror("execvp error");//打印上一次系统调用接口使用的错误原因exit(0);}//4、父进程进行进程等待wait(NULL);}return 0;
}
运行测试:
如果觉得这篇博客对你有用记得一键三连哦!!!
Linux 原来实现一个shell这么容易!(史上最简单详细)相关推荐
- 史上最简单详细的Hadoop完全分布式集群搭建
一.安装虚拟机环境 Vmware12中文官方版 链接:https://pan.baidu.com/s/1IGKVfaOtcFMFXNLHUQp41w 提取码:6rep 激活秘钥:MA491-6NL5Q ...
- 史上最简单的spark系列教程 | 完结
<史上最简单的spark系列教程>系列: 与其说是教程不如说是改良后的个人学习笔记|| 教程参考自:<spark官方文档>,<spark快速分析>,<图解Sp ...
- linux只有上传文件到站点,史上最简单的上传文件到linux系统方法
史上最简单的上传文件到linux系统方法 工具/原料 linux,windows filezilla 方法/步骤 1 下载 Filezilla client工具,此客户端为免费软件,下载完成后安装,安 ...
- 史上最简单的spark教程第十七章-快速开发部署第一个sparkStreaming+Java流处理程序
第一个流处理程序sparkStreaming+Java 史上最简单的spark教程 所有代码示例地址:https://github.com/Mydreamandreality/sparkResearc ...
- 手把手教你配置linux下C++开发工具——vim+ycm(YouCompleteMe),支持基于语义的自动补全和第三方库补全(史上最简单、史上最透彻、史上最全的终极解决方案)
截止到目前,vim稳定版本已经到了8.2+,ycm(YouCompleteMe的简称)最新版本与几年前的安装配置截然不同了.之前网上很多教程也教不得法,生搬硬套,没有讲透彻.所以,才下定决心写一篇自认 ...
- 史上最简单的SpringCloud教程 | 第十篇: 高可用的服务注册中心
转自:https://blog.csdn.net/forezp/article/details/81041101 文章 史上最简单的 SpringCloud 教程 | 第一篇: 服务的注册与发现(Eu ...
- 史上最简单的git教程搭配Github和Gitee一起食用更佳
史上最简单的git教程 开始之前 git的最简单使用 1. 安装 2. 配置 2.1 用户信息 3. 最基本使用 Github 1. 首先你需要一个账号 2. 你需要一个仓库 Gitee 开始之前 g ...
- 史上最简单MySQL教程详解(进阶篇)之存储引擎介绍及默认引擎设置
什么是存储引擎? MySQL存储引擎种类 MyISAM 引擎 InnoDB引擎 存储引擎操作 查看存储引擎 存储引擎的变更 修改默认引擎 什么是存储引擎? 与其他数据库例如Oracle 和SQL Se ...
- 史上最简单Robotium跨进程操作实践——基于ADB框架
楼主原创,分享不易,转载请注明出处,谢谢. 2015年2月3日更新: 有些朋友在用真机尝试本方法时,抛出了InputStream cannot be null的异常.该异常是由于adb运行在robot ...
最新文章
- 从经典问题开始教你如何入门计算机视觉!贴心!
- 【python教程入门学习】如何把Python学好
- 运维自动化之zabbix (Discovery)(9)
- php对mongo操作问题
- vue之父子组件通信
- android int与String的转换
- 移动WEB的页面布局
- The 15th UESTC Programming Contest Preliminary K - Kidd1ng Me? cdoj1565
- 正则表达式(一) -- 元字符(转)
- linux 端口映射设置
- android 敏感词过滤器,android 过滤敏感词主要类
- 天线分类特征学习笔记(1)偶极子天线
- 信号与系统matlab实验报告,信号与系统实验报告.doc
- 简练网软考知识整理-风险应对措施之应急计划弹回计划权变措施
- 解决com.lowagie.text.DocumentException: Font 'STSong-Light' with 'UniGB-UCS2-H' is not recognized.
- 微信小程序+.NET(五) 音频格式转换-从.mp3到.wav
- python程序设计大赛题目_第三第四题,这是Python程序设计的题目,
- 4位先行进位加法器的vhdl程序_VHDL精密,Verilog简洁,但要写好都要遵守这25条通则...
- Batch Renormalization
- IB36分斩获藤校?看艺术设计类专业
热门文章
- matlab自家自减,【求助】VC环境下自增(++)自减(--) - 信息科学 - 小木虫 - 学术 科研 互动社区...
- easyui dialog 不执行页面js_Spring Security(六):前端菜单,角色权限页面的搭建
- java sqlserver 二进制_Java将图片资源以二进制的形式保存到Sqlserver数据库中
- python竖着输出编码_在Python中使用管道标准输出时设置正确的编码
- AndroidUtilCode框架 fileutils学习总结
- xutils retry error, curr request is null
- Jsp+Servlet+Mysql实现的在线鲜花商城源码
- List<T>和List<?>的区别
- 基于JAVA+SpringMVC+Mybatis+MYSQL的毕业论文设计管理系统
- Python基础 ( 十 ) —— 面向对象(多态、封装、反射、动态导入)