【Linux】进程篇(补):简易 shell 的实现(进程深刻理解、内建命令的使用)
文章目录
- makefile
- mybash.c
代码逻辑框架(重要的是,边写边查!)
- 命令行提示符,fflush 刷新显示
- 获取 输入的 有效字符串,定义一个字符数组,用 fgets 从键盘上获取(注意处理命令行输入时的回车)
- 字符串切割,C语言函数 strtok,子串保存到指针数组
- 创建子进程,执行代码
细节:
-
ls 的配色方案
-
内建命令的处理
cd ..cd /这样的命令,需要让 bash 自己执行的,叫做 内建命令 / 内置命令export,一般用户自定义的环境变量,在 bash 中要用户自己来进行维护,不要用一个经常被覆盖的缓冲区来保存环境变量!!!env,我们一般需要 env 时,都要查看的是自己进程的环境列表,这里就是查看 bash 的环境列表。echo,利用指针查找和输出echo $?,
其实我们之前提到过的几乎所有环境变量命令,都是 内建命令。
makefile
mybash:mybash.cgcc -o $@ $^
.PHONY:clean
clean:rm -f mybash
mybash.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>#define MAX 1024
#define ARGC 64
#define SEP " "int split(char *commandstr, char *argv[])
{assert(commandstr);assert(argv);argv[0] = strtok(commandstr, SEP);if(argv[0] == NULL) return -1;int i = 1;while((argv[i++] = strtok(NULL, SEP)));//int i = 1;//while(1)//{// argv[i] = strtok(NULL, SEP);// if(argv[i] == NULL) break;// i++;//}return 0;
}void debugPrint(char *argv[])
{for(int i = 0; argv[i]; i++){printf("%d: %s\n", i, argv[i]);}
}void showEnv()
{extern char **environ;for(int i = 0; environ[i]; i++) printf("%d:%s\n", i, environ[i]);
}int main()
{//当我们在进行 env 查看的时候,我们想查的是谁的环境变量列表?父进程 bash 的环境变量列表int last_exit = 0;char myenv[32][256];int env_index = 0;while(1){char commandstr[MAX] = {0}; // 命令行输入的,完整字符串char *argv[ARGC] = {NULL}; // 命令行输入的,子串// 1printf("[Stella@hostname currpath]# ");fflush(stdout); // 把数据从缓冲区刷新显示出来// 2char *s = fgets(commandstr, sizeof(commandstr), stdin);assert(s);(void)s; // 保证在release方式发布的时候,因为去掉assert了,所以s就没有被使用,而带来的编译告警, 什么都没做,但是充当一次使用// abcd\n\0commandstr[strlen(commandstr)-1] = '\0';// 3// "ls -a -l" -> "ls" "-a" "-l"int n = split(commandstr, argv);if(n != 0) continue;//debugPrint(argv);// (1)【添加 ls 命令的配色方案】if(strcmp(argv[0], "ls") == 0) {int pos = 0;while(argv[pos]) pos++;argv[pos++] = (char*)"--color=auto";加配色方案argv[pos] = NULL; // 比较安全的做法}// (2)【内建命令】// cd .. / cd /: 让bash自己执行的命令,我们称之为 内建命令/内置命令if(strcmp(argv[0], "cd") == 0){//说到底,cd 命令,重要的表现就如同 bash 自己调用了对应的函数if(argv[1] != NULL) chdir(argv[1]); // chdir是一个系统调用函数,可以改变当前工作路径continue;}else if(strcmp(argv[0], "export") == 0) // 其实我们之前学习到的所有的(几乎)环境变量命令,都是内建命令{if(argv[1] != NULL){strcpy(myenv[env_index], argv[1]);putenv(myenv[env_index++]);}continue;}else if(strcmp(argv[0], "env") == 0){showEnv();continue;}else if(strcmp(argv[0], "echo") == 0){// echo $PATHconst char *target_env = NULL;if(argv[1][0] == '$') {if(argv[1][1] == '?'){printf("%d\n", last_exit);continue;}else target_env = getenv(argv[1]+1); // "abcdefgif(target_env != NULL) printf("%s=%s\n", argv[1]+1, target_env);}continue;}// 4// version 1pid_t id = fork();assert(id >= 0);(void)id;if(id == 0){if(redir_type != REDIR_NONE){//1. 存在文件的//2. redir_type获取到//3. dup2;}//childexecvp(argv[0], argv);exit(1);}int status = 0;pid_t ret = waitpid(id, &status, 0);if(ret > 0){last_exit = WEXITSTATUS(status);}//printf("%s\n", commandstr);}
}相关文章:
【Linux】进程篇(补):简易 shell 的实现(进程深刻理解、内建命令的使用)
文章目录 makefilemybash.c 代码逻辑框架(重要的是,边写边查!) 命令行提示符,fflush 刷新显示获取 输入的 有效字符串,定义一个字符数组,用 fgets 从键盘上获取(注意处理命令行输入…...
django Ajax--前后端数据交互
一.Django的Ajax和JavaScript的Ajax Django的Ajax和JavaScript的Ajax实质上是指同一种技术,即异步JavaScript和XML(Asynchronous JavaScript and XML)。它允许在不刷新整个页面的情况下,通过前后端之间的异步交互来获取或发送数据…...
【嵌入式学习笔记】嵌入式入门1——GPIO
1.什么是GPIO General Purpose Input Output,即通用输入输出端口,简称GPIO,作用是负责采集外部器件的信息或者控制外部器件工作,即输入输出。 2.STM32 GPIO简介 2.1.GPIO特点 不同型号,IO口数量可能不一样&#x…...
[SQL挖掘机] - 多表连接: union
介绍: sql中的union是用于合并两个或多个select语句的结果集的操作符。它将多个查询的结果合并成一个结果集,并自动去除重复的行。请注意,union操作要求被合并的查询返回相同数量和类型的列。 用法: union的基本语法如下: select_stateme…...
AI面试官:SQL Server数据库(三)
AI面试官:SQL Server数据库(三) 当涉及到.NET工程师中关于SQL Server数据库的面试题时,主要考察候选人的数据库知识、SQL查询能力、数据库设计和优化等方面。 文章目录 AI面试官:SQL Server数据库(三)31. 数据库并发控制是什么?数据库有哪些常见的并发控制机制?32. 什…...
python刑事案卷图片转pdf
分两步,第一步是转图片,第二步是合并。 # -*- coding: utf-8 -*- import glob,os from PIL import Imagedef convert_to_pdf(path):# 打开图片文件img Image.open(path)# 将图片转换为 PDF,并保存到同名文件pdf_path os.path.splitext(path…...
vue使用driver.js完成页面引导的功能
需求:给客户做一个页面引导,教客户怎么做 效果: driverjs官方文档 一.安装driver.js # Using npm npm install driver.js# Using pnpm pnpm install driver.js# Using yarn yarn add driver.js 二.在自己需要引导的页面上引入driver.js i…...
学习中遇到的好博客
c日志工具之——log4cpp ECU唤醒的本质就是给ECU供电。 小文件:零拷贝技术 传输大文件:异步 IO 、直接 IO:如何高效实现文件传输:小文件采用零拷贝、大文件采用异步io直接io (123条消息) Linux网络编程 | 彻底搞懂…...
在CSDN学Golang云原生(Kubernetes集群安全)
一,ABAC授权模式 Kubernetes ABAC(Attribute-Based Access Control)授权模式是一种基于属性的访问控制模型,它可以根据用户或组的属性决定是否允许他们访问 Kubernetes 集群中的资源。 在使用 ABAC 授权模式时,管理员…...
浅谈深度神经网络
Deep neural networks are completely flexible by design, and there really are no fixed rules when it comes to model architecture. -- David Foster 前言 神经网络 (neural network) 受到人脑的启发,可模仿生物神经元相互传递信号。神经网络就是由神经元组成…...
『C语言初阶』第六章-操作符详解
前言 今天小羊又来为铁汁们更新C语言初阶的操作符详解,我们在平时写代码时总会写到一些算术操作符和赋值操作符,可是当铁汁们遇到其他的操作符时,就会望而却步,甚至写出一些bug,所以这期我给铁汁们带来新鲜出炉的操作…...
企业知识文档管理+群晖nas安全云存储
企业知识管理系统,利用软件系统或其他工具的企业管理方法,利用软件系统或其他工具,对组织中大量的有价值的方案、策划、成果、经验等知识进行分类存储和管理,积累知识资产避免流失,促进知识的学习、共享、培训、再利用…...
《吐血整理》进阶系列教程-拿捏Fiddler抓包教程(9)-Fiddler如何设置捕获Https会话
1.简介 由于近几年来各大网站越来越注重安全性都改成了https协议,不像前十几年前直接是http协议直接裸奔在互联网。还有的小伙伴或者童鞋们按照上一篇宏哥的配置都配置好了,想大展身手抓一下百度的包,结果一试傻眼了,竟然毛都没有…...
对比CahtGPT Bard Claude2对中文的理解
对比CahtGPT Bard Claude2对中文的理解 今天简单测试了一下目前这三个很火的模型对中文的理解能力 简单问题 鲁迅和周树人的关系 Bard CahtGPT Claude 介绍一下平凡的世界这本书 Bard CahtGPT...
安全测试国家标准解读——并发程序安全
本系列文章主要围绕《GB/T 38674—2020 信息安全技术 应用软件安全编程指南》进行讲解,该标准是2020年4月28日,由国家市场监督管理总局、国家标准化管理委员会发布,2020年11月01日开始实施。我们对该标准中一些常见的漏洞进行了梳理ÿ…...
《吐血整理》进阶系列教程-拿捏Fiddler抓包教程(12)-Fiddler设置IOS手机抓包,你知多少???
1.简介 Fiddler不但能截获各种浏览器发出的 HTTP 请求,也可以截获各种智能手机发出的HTTP/ HTTPS 请求。 Fiddler 能捕获Android 和 Windows Phone 等设备发出的 HTTP/HTTPS 请求。同理也可以截获iOS设备发出的请求,比如 iPhone、iPad 和 MacBook 等苹…...
MySQL中锁的简介——行级锁
1.行级锁概念及分类 可通过以下语句查看意向锁和行锁的加锁情况: select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_locks;InnoDB的行锁是针对于索引加的锁,不通过索引条件检索数据࿰…...
4 个最常见的自动化测试挑战及应对措施
有人说:“杂乱无章的自动化只会带来更快的混乱。”不仅更快,而且是更严重、更大的混乱。如果使用得当,自动化可以成为测试团队中令人惊叹的生产力助推器和系统的质量增强器。自动化测试的关键是要正确运用,这是初始最困难的部分。…...
23款奔驰GLE450豪华型升级AMG直瀑式中网,战斗感立马提升了一个档次
奔驰GLE450豪华型升级AMG竖杠中网前进气格栅,AMG中网竖杠格栅,镀铬饰条呈圆弧状,色泽均衡,质感顺滑,极富冲击力。AMG专属字标,与中网卡扣装配紧密,凸显AMG的身份象征,点睛之笔又不显…...
ALLEGRO之Logic
本文主要讲述ALLEGRO的Logic菜单。 (1)Net Logic:暂不清楚; (2)Net Schedule:暂不清楚; (3)AssignDifferential Pair:暂不清楚; &a…...
(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...
【51单片机】4. 模块化编程与LCD1602Debug
1. 什么是模块化编程 传统编程会将所有函数放在main.c中,如果使用的模块多,一个文件内会有很多代码,不利于组织和管理 模块化编程则是将各个模块的代码放在不同的.c文件里,在.h文件里提供外部可调用函数声明,其他.c文…...
小智AI+MCP
什么是小智AI和MCP 如果还不清楚的先看往期文章 手搓小智AI聊天机器人 MCP 深度解析:AI 的USB接口 如何使用小智MCP 1.刷支持mcp的小智固件 2.下载官方MCP的示例代码 Github:https://github.com/78/mcp-calculator 安这个步骤执行 其中MCP_ENDPOI…...
UE5 音效系统
一.音效管理 音乐一般都是WAV,创建一个背景音乐类SoudClass,一个音效类SoundClass。所有的音乐都分为这两个类。再创建一个总音乐类,将上述两个作为它的子类。 接着我们创建一个音乐混合类SoundMix,将上述三个类翻入其中,通过它管理每个音乐…...
