[Linux][简易实现shell]详细解读 + 代码实现

在这里插入图片描述

  • shell执行的命令,通常有两种
    • 第三方提供的,对应在磁盘的可执行程序(由子程序执行)
    • shell内部,自己实现的方法,由自己(父进程)来执行
      • 有些命令是会影响shell本身的
      • 如:cd、export(添加环境变量)
  • 思路:
    1. 获取命令行
    2. 解析命令行
    3. 建立一个子进程 – fork
    4. 替换子进程 – execvp
    5. 父进程等待子进程tuichu – wait
  • 实现:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>#define NUM 1024
#define SIZE 32
#define SEP " "char cmd_line[NUM] = {0}; // 保存用户键入的命令行字符串
char *g_argv[SIZE] = {NULL}; // 保存解析之后的字符串
char g_valbf[NUM]; // buffer,用来存储环境变量// shell运行原理 --> shell解析命令&&等待子进程,子进程执行命令
int main()
{// 命令行解释器,是一个常驻内存的进程,不退出while(1){// 0.打印提示信息printf("[SnowK@localhost minishell]# ");fflush(stdout); // 手动刷新缓冲区// 1.读取命令if(fgets(cmd_line, sizeof cmd_line, stdin) == NULL){// 读取失败,重新尝试读取continue;}cmd_line[strlen(cmd_line) - 1] = '\0'; // 键入类似"ls -l\n",但是没有\0,所以手动置换// 2.解析命令:"ls -l -a" --> "ls" "-l" "-a"int index = 1;g_argv[0] = strtok(cmd_line, SEP); // 第一次调用,要传入原始字符串// 为实现方便,为ls添加颜色和类似ll的别名,就做特殊处理了// 有兴趣的小伙伴可以自己实现更智能的做法if(strcmp(g_argv[0], "ls") == 0){g_argv[index++] = "--color=auto";}if(strcmp(g_argv[0], "ll") == 0){g_argv[0] = "ls";g_argv[index++] = "-l";g_argv[index++] = "--color=auto";}while(g_argv[index++] = strtok(NULL, SEP)); // 第二次,如果还要继续解析原字符串,传NULL// export MYVAL=SnowKif(strcmp(g_argv[0], "export") == 0 && g_argv[1] != NULL){strcpy(g_valbf, g_argv[1]);putenv(g_valbf);continue;// 思考为什么不能用下面的代码?// putenv(g_argv[1]);// strtok裁剪出来的子字符串,是用一个指针指向子字符串的// 并不是单独拿出来的,每次一次循环,会覆盖原来的cmd_line// 则g_argv中的各个子字符串就指向了错误的字符串// 如:g_argv[1]存的地址,依然是cmd_line中的地址}// 2.5 内置命令,即让父进程shell自己执行的命令// 内置命令本质就是shell里的一个函数调用if(strcmp(g_argv[0], "cd") == 0){if(g_argv[1] != NULL){chdir(g_argv[1]); // chdir 系统调用接口 --> cd pathcontinue;}}// 3.fork(),派送子进程pid_t id = fork();if(id == 0){// childprintf("child start\n");printf("----------------------------\n");execvp(g_argv[0], g_argv);exit(1);}// parentint status = 0;int ret = waitpid(id, &status, 0);if(ret > 0){printf("child success, exit code:%d\n", WEXITSTATUS(status));printf("----------------------------\n");}}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/616690.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分布式技术--------------ELK大规模日志实时收集分析系统

目录 一、ELK日志分析系统 1.1ELK介绍 1.2ELK各组件介绍 1.2.1ElasticSearch 1.2.2Kiabana 1.2.3Logstash 1.2.4可以添加的其它组件 1.2.4.1Filebeat filebeat 结合logstash 带来好处 1.2.4.2缓存/消息队列&#xff08;redis、kafka、RabbitMQ等&#xff09; 1.2.4.…

【大语言模型】轻松本地部署Stable Diffusion

硬件要求&#xff1a; 配备至少8GB VRAM的GPU&#xff0c;如果你的电脑只有CPU&#xff0c;请看到最后。根据部署规模&#xff0c;需要足够的CPU和RAM。 软件要求&#xff1a; Python 3.7或更高版本。支持NVIDIA GPU的PyTorch。Hugging Face的Diffusers库。Hugging Face的Tr…

【数据结构】复习题(二)

Hello&#xff01;大家好&#xff0c;这一篇数据结构复习题是我上个学期复习的时候写的&#xff08;刚刚在草稿箱发现了&#xff01;&#xff09;有一些题目过程都是配了图片的&#xff0c;希望对正在复习数据结构的宝宝们有帮助哦&#xff01;(还有一个数据结构复习题(一)可以…

Linux驱动中断下半部的三种方法

大家好&#xff0c;今天给大家介绍Linux驱动中断下半部的三种方法&#xff0c;文章末尾附有分享大家一个资料包&#xff0c;差不多150多G。里面学习内容、面经、项目都比较新也比较全&#xff01;可进群免费领取。 Linux驱动中断下半部的三种主要方法如下&#xff1a; 软中断&…

java数据结构与算法刷题-----LeetCode693. 交替位二进制数

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 文章目录 位运算 位运算 解题思路&#xff1a;时间复杂度O( 1 1 1)&#…

Open CASCADE学习|实现Extrude功能

首先定义了一些基本的几何元素&#xff0c;如线、圆和平面&#xff0c;然后使用makeExtrudebydir函数来对一个面进行挤出操作。下面是详细过程&#xff1a; 定义Extrude函数&#xff1a;makeExtrudebydir函数接受一个TopoDS_Shape对象和一个gp_Vec对象作为参数。TopoDS_Shape是…

遥感卫星:探索地球的科技之旅

遥感卫星是人类探索地球、理解地球、保护地球的重要工具&#xff0c;其发展历程承载了人类对地球的探索与认知的历程。从最初的概念到如今的高科技应用&#xff0c;遥感卫星技术的发展见证了人类科技的不断进步与创新。 初心萌芽&#xff1a; 遥感卫星的发展始于20世纪中叶&…

Golang | Leetcode Golang题解之第26题删除有序数组中的重复项

题目&#xff1a; 题解&#xff1a; func removeDuplicates(nums []int) int {n : len(nums)if n 0 {return 0}slow : 1for fast : 1; fast < n; fast {if nums[fast] ! nums[fast-1] {nums[slow] nums[fast]slow}}return slow }

window10轻松使用k8s

Docker Desktop安装篇 1、win10安装 1、下载安装包 https://www.docker.com/products/docker-desktop/ 官网下载安装包 2、配置win10支持虚拟化 不勾选Hyper-V&#xff0c;容易出错 3、安装WSL配置window支持linux Windows Subsystem for Linux (WSL) 安装 Linux 子系统&am…

一辆汽车的节拍时间是怎样的?

节拍时间&#xff0c;又称 takt time&#xff0c;是德语中“节奏”的意思。在汽车制造业中&#xff0c;它指的是按照客户需求和生产计划&#xff0c;生产一辆汽车所需的时间。这个时间是固定的&#xff0c;它决定了生产线上每个工序的操作速度和节奏&#xff0c;是生产线上所有…

Fuel tank position

Fuel tank position 汽车油箱位置在哪里&#xff0c;加油的时候就不会听错方向

IEDA 启动项目时出现 java: java.lang.OutOfMemoryError: GC overhead limit exceeded 异常

问题 通过Idea启动项目时&#xff0c;出现java: java.lang.OutOfMemoryError: GC overhead limit exceeded 内存溢出问题&#xff1b; 解决方案 错误是发生在编译阶段&#xff0c;而不是运行阶段&#xff1a; 【1】idea编译Java项目使用的虚拟机和idea软件自身使用的虚拟机是…