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

14.C 语言实现一个迷你 Shell

文章目录

    • 项目名称:用 C 语言实现一个迷你 Shell
      • 一、项目简介
      • 二、完成的功能
      • 三、代码部分
      • 四、程序运行流程
      • 五、用到的知识点解析


项目名称:用 C 语言实现一个迷你 Shell

一、项目简介

本项目是一个用 C 语言编写的简易命令行解释器(Shell),支持用户输入命令、解析参数、创建子进程执行命令,并阻塞等待子进程结束。它模拟了 Linux 下 Bash 的基本行为,适合初学者练习进程控制和字符串处理。


二、完成的功能

  • 显示提示符(包含当前路径)
  • 读取用户输入
  • 使用 strtok() 解析命令参数
  • 使用 fork() 创建子进程
  • 使用 execvp() 执行命令
  • 使用 waitpid() 阻塞等待子进程结束
  • 支持 exit 命令退出 Shell

三、代码部分

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>#define PWD "PWD"                  // 环境变量名,用于获取当前路径
#define LINE_NUM 1024              // 命令最大长度
#define OPT_NUM 64                 // 参数最大个数char lineCommand[LINE_NUM];        // 这里所存放的是已经提取完成的
char* myargv[OPT_NUM];             // 存放分割后的参数指针数组// 执行进程程序替换使用 execvp
void do_exec(char** myargv_)
{pid_t id = fork();             // 创建子进程assert(id >= 0);               // 保证 fork 成功if (id == 0){// 执行进程程序替换使用 execvpexecvp(myargv_[0], myargv_);perror("execvp failed");   // 如果 execvp 失败,打印错误信息exit(1);                   // 子进程退出}// 父进程等待子进程结束,这里我就直接选用阻塞式等待int status;pid_t ret = waitpid(id, &status, 0);printf("child id:%d, sig code:%d, exit code:%d\n", ret, status & 0x7F, (status >> 8) & 0xFF);
}// 完成字符串切割,这里调用 strtok
char** do_prase(char* buff)
{int i = 0;char* token = strtok(buff, " ");while (token != NULL){myargv[i++] = token;token = strtok(NULL, " "); // 这表示从上一次分割的位置开始继续进行分割}myargv[i] = NULL;              // 最后一个参数设为 NULL,方便 execvp 使用return myargv;
}// 这里就会像 bash 一样输出行信息还有当前路径
int do_face()
{printf("zy@Cent %s:", getenv(PWD));fflush(stdout);// 获取用户输入char* s = fgets(lineCommand, sizeof(lineCommand) - 1, stdin);assert(s != NULL);(void)s;// 清除最后一个 \nlineCommand[strlen(lineCommand) - 1] = '\0';// 支持 exit 命令退出 shellif (strcmp(lineCommand, "exit") == 0)return -1;// 这里加入了断言,再输入不为空的情况去进行字符串的剪切和存储// 剪切完成后得到的就是一个指针数组,再返回这个数组的地址,所以我这里的返回值就必须是二级指针do_prase(lineCommand);return 0;
}// 这里写一个死循环可以去持续读取执行指令
int main()
{while (1){// 1、对指令进行分割提取if (do_face() < 0)break;// 2、调用进程替换进行执行,然后父进程等待do_exec(myargv);}return 0;
}

四、程序运行流程

  1. 显示提示符(当前路径)
  2. 读取用户输入
  3. 判断是否输入 exit,是则退出
  4. 使用 strtok() 分割命令参数
  5. 创建子进程并执行命令
  6. 父进程等待子进程结束
  7. 回到第 1 步,继续循环

五、用到的知识点解析

技术点说明
fgets()安全读取用户输入
strtok()字符串切割,提取命令参数
fork()创建子进程
execvp()执行命令,自动搜索路径
waitpid()阻塞等待子进程结束
exit 命令通过字符串判断实现退出功能

http://www.dtcms.com/a/486804.html

相关文章:

  • 【理解React Hooks与JavaScript类型系统】
  • 如何使用PyTorch高效实现张量的批量归一化原理与代码实战
  • 文心快码Comate3.5S更新,用多智能体协同做个健康管理应用
  • 江苏赛孚建设工程有限公司网站做php门户网站那个系统好
  • OpenCV5-图像特征harris-sift-特征匹配-图像全景拼接-答题卡识别判卷
  • 计算机网络经典问题透视:以太网发送512bit后,碰撞还可能发生吗?
  • 免费网站管理系统昌邑建设网站
  • 初始Spring
  • wordpress站点标题看不到合肥建站企业
  • 网站空间哪家公司的好上海专业网站建设价
  • 考研数学笔记(概率统计篇)
  • HT6809:重塑音频体验的立体声 D 类功率放大器
  • Flutter对话框AlertDialog使用指南
  • 玩Android Flutter版本,通过项目了解Flutter项目快速搭建开发
  • 大数据毕业设计选题推荐-基于大数据的商店购物趋势分析与可视化系统-大数据-Spark-Hadoop-Bigdata
  • 网站标题符号的应用龙岩整站优化
  • 运维知识图谱的构建与应用
  • MySQL中RUNCATE、DELETE、DROP 的基本介绍
  • php企业网站 源码asp网站耗资源
  • 【LeetCode】四数之和
  • 网站进不去怎么解决网络营销策略
  • 旗讯 OCR:破解全行业表格处理痛点,让数据从 “识别” 到 “可用” 一步到位
  • 测试开发笔试
  • 数据库的创建,查看,修改,删除,字符集编码和校验操作
  • C语言初步学习:数组的增删查改
  • 【组队学习】Post-training-of-LLMs TASK02
  • 系统设计相关知识总结
  • 做视频的模板下载网站xunsearch做搜索网站
  • 做企业网站需要人维护么电子商务推广
  • Linux驱动开发原理详解:从入门到实践