Linux C项目 | 迷你命令行解释器 (1)

发布时间:2026/10/25 20:31:13

Linux C项目 | 迷你命令行解释器 (1) 简介这是一个纯C实现的简单Linux Shell用于巩固Linux应用编程学习适合学到线程阶段的巩固练习。首先做一个项目得知道这个项目为什么存在命令行解释器 Shell 功能是用于解析用户命令然后调用操作系统的程序就像是用户和操作系统之间的 翻译官调度员。Shell是指命令行解释器这一大类如Bash是Linux的一个具体的Shell、CMD和PowerShell是Windows的具体的Shell。常打开的终端是给Shell提供输入输出界面的负责接收键盘的输入和显示程序的输出终端 → (提供输入输出窗口) → Shell (解析命令、调用程序) → 操作系统内核这个项目只实现了一个最小可用的Shell1.交互式命令循环显示命令提示符 持续读取输入、解析、执行直到用户退出2.命令输入读取可以从标准输入读取单行命令使用手写的动态缓冲区3.命令解析将输入按空白字符拆分成命令和参数生成execvp可用的参数数组4.内置命令支持cd、help、exit三个内置命令5.外部命令执行非内置命令创建子进程调用执行程序父进程等待子进程命令结束6.错误处理cd缺少参数、fork失败等失败信息都要能够输出错误信息保持shell主循环能够继续设计模块一实现read_line( ) 读取用户的输入设计函数read_line( ) → 让用户输入读取用户的输入 → 放到内存 → 返回内存地址1.让用户输入并获取内容有这些函数可以实现函数用途数据源getchar (标准IO)从标准流中读取一个字符stdin标准输入流fgetc (标准IO)从指定流中读取一个字符FILE *fgets (标准IO)从指定流中读取一行文本FILE *getline (POSIX 标准IO)动态读取指定流一行文本FILE *read (文件IO)从底层读取数据文件描述符 fdscanf (标准IO)按格式读取标准流stdinfscanf (标准IO)从指定流中按格式读取FILE *先说结论本项目选择的是 getchar实现因为这个需求只是简单的文本处理不需要操作底层细节因此不用文件IO那为什么不选择其他标准IO因为已知是从键盘标准流读取数据的直接使用getchar读取标准流即可更简洁不需要再去指定流那为什么是一个字符一个字符读取因为本项目主要是为了学习巩固底层细节控制什么时候结束、自己malloc以及realloc所以选择getchar实现那为什么不用scanf因为scanf遇到格式化解析 %s 的时候遇到空格会停止不适合用来输入命令该需求完全可以使用getline快速实现读取命令行系统会帮你读取整行并且分配好内存。使用getchar其实就是把getline背后要做的事情实现了一遍。那读取一行不是也可以使用fgets吗是的不过使用fgets的话需要提前准备固定大小的数组可能会遇到超过容量的问题getline可以动态扩容2.读取的字符存在哪里因为不知道用户会输入多长的命令所以不应该把buffer写死应该先malloc申请一块内存存放后面如果出现了超出内存越界的情况再realloc改变动态内存的大小进行动态扩容代码实现第一版核心代码#include stdio.h #include stdlib.h char *read_line(){ // 声明读函数 读取字符串需要返回一个字符串地址 因此使用char *来接收这个字符串的首地址 #define BUFFER_SIZE 1024 // 宏定义 固定配置初始缓冲区大小、每次扩容的大小 int bufsize BUFFER_SIZE; // 声明缓冲区大小变量 int c; // 用来接收用户的输入 注意getchar的返回类型是int类型 char *buffer malloc(sizeof(char) * bufsize); // 申请一块内存 用于存放字符 返回内存地址使用char *接收 int position 0; // 用来标记位置读到哪里 while(1){ c getchar(); if (c EOF){ // 数据读完了 结束 exit(EXIT_SUCCESS); } else if (c \n){ // 读到换行符 读完了 buffer[position] \0; // 将换行符换成字符串结束标志 \0 return buffer; } else{ // 读的过程 buffer[position] c; // 把读到的字符存到数组 } position; // 读完移动位置 } } int main(void){ return 0; }敲完代码进行检查发现以下问题1.没有进行malloc的检查因为malloc不保证一定成功系统内存空间可能不足2.没有进行动态扩容可能发生内存越界修改后的代码#include stdio.h #include stdlib.h char *read_line(void){ // 读取字符串需要返回一个字符串地址 因此使用char *来接收这个字符串的首地址 #define BUFFER_SIZE 1024 // 宏定义 固定配置初始缓冲区大小、每次扩容的大小 int bufsize BUFFER_SIZE; // 声明缓冲区大小变量 int c; // 用来接收用户的输入 注意getchar的返回类型是int类型 char *buffer malloc(sizeof(char) * bufsize); // 申请一块内存 用于存放字符 返回内存地址使用char *接收 int position 0; // 用来标记位置读到哪里 // malloc检查 if(!buffer){ // 如果malloc申请失败 异常退出 fputs(malloc申请内存失败\n,stderr); // 因为不需要格式化输出 这里使用fputs输出到标准错误流 exit(EXIT_FAILURE); // 异常退出 } while(1){ c getchar(); if (c EOF){ // 数据读完了 结束 exit(EXIT_SUCCESS); // 程序正常退出 } else if (c \n){ // 读到换行符 读完了 buffer[position] \0; // 将换行符换成字符串结束标志 \0 → 字符串一定要有结束标志 return buffer; } else{ // 读的过程 buffer[position] c; // 把读到的字符存到数组 } position; // 读完移动位置 // 当内存满了需要动态扩容 if(position bufsize){ bufsize BUFFER_SIZE; // 再增加1024字节 buffer realloc(buffer,bufsize); // realloc检查 if(!buffer){ fputs(realloc申请内存失败\n,stderr); exit(EXIT_FAILURE); } } } } int main(void){ return 0; }疑问1为什么 bufsize BUFFER_SIZE 这里直接增加了1024字节而不是每次增加一个字节这确实会造成一点内存空间的浪费但不是严重的浪费这是牺牲一点内存空间去换取扩容效率。因为realloc的流程是如果原来的内存后面没有足够连续的内存空间 → 找到一块更大的新内存空间 → 把旧数据复制过去 → 释放旧的内存 → 返回新的内存空间地址。如果每次增加一个字节就需要频繁的扩容浪费大量的时间降低效率模块一已设计开发完成梳理一下链路画草图辅助梳理一下链路
延伸阅读

更多相关文章

2026/10/24 9:42:56

纯Python手写CNN:从零实现卷积、池化与反向传播

简介:手写实现的二维卷积神经网络(2D CNN)Python代码,面向希望深入理解CNN底层原理的Python学习者与图像处理入门者,适合在PyCharm中运行调试。资源共2个文件,包括一个.py源码文件和一个.docx实验报告&…

2026/10/25 19:04:54

WMM2020COF地磁模型系数文件解析:从球谐展开到工程实现

简介:这份压缩包为WMM2020地磁模型的CGGM计算工具包,面向钻井、物探等需要高精度地磁参考的工程师与科研人员,用于解决2020年地磁模型系数解析、磁场分量计算及数据格式转换等问题。内含7个文件,包括3个MATLAB脚本、3个TXT数据文本…

2026/10/25 20:30:06

MLOps工具链协同实战:Neptune、MLflow、WhyLabs与Arize集成指南

1. 项目概述:为什么一篇“翻译稿”值得单独成文?NeptuneAI 博客中文翻译(六十八)——光看标题,你可能觉得这不过是一次常规的文档搬运。但如果你在 MLOps 工程一线待过半年以上,就会明白:这类翻…

2026/10/25 20:25:06

ASP.NET Core Excel导入导出:EPPlus+ExcelDataReader生产实践

简介:本资源是一套基于ASP.NET Core WebAPI的Excel文件处理实战项目,面向C#后端开发者及.NET全栈工程师,解决Web服务中高频的Excel导入导出需求。项目完整集成EPPlus(用于高效导出OpenXML格式Excel)与ExcelDataReader&…

2026/10/25 20:25:06

eWebEditor v0.1.4 For JSP 部署与 Tomcat 避坑

简介:eWebEditor在线文本编辑器 v0.1.4 For JSP 是面向JSP开发者的富文本编辑组件,主要解决网页内容录入、排版与多媒体插入问题,适合后台管理、内容发布等页面集成可视化编辑能力。压缩包共264个文件,以186个gif界面素材、27个cs…

2026/10/25 20:20:05

科研汇报PPT模板下载:拆解母版版式与python-pptx自动化

简介:面向课题总结、答辩汇报与学术交流场景,科研汇报PPT模板下载提供一套结构完整、可定制的演示文稿方案,帮助科研人员与学生解决排版耗时、信息层级不清和专业性不足的问题。压缩包为rar格式,共4个文件、约54.23MB,…

2026/10/25 0:02:22

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/25 0:02:23

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/25 0:02:23

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

2026/10/25 0:02:22

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/25 0:02:23

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/25 0:02:23

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑