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

【Linux课程学习】:《简易版shell实现和原理》 《哪些命令可以让子进程执行,哪些命令让shell执行(内键命令)?为什么?》

🎁个人主页:我们的五年

🔍系列专栏:Linux课程学习 

🌷追光的人,终会万丈光芒

🎉欢迎大家点赞👍评论📝收藏⭐文章

目录

打印命令行提示符(PrintCommandLine):

1.USER和LOGNAME(用户名):

2.HOSTNAME和PWD:

获取命令行信息(GetCommadLine)

读取时,处理换行符:

解析命令行(ParseCommandLine)

执行命令(ExecuteCommand)

哪些命令可以让子进程执行,哪些命令不能让子进程执行?为什么?

通过getcwd获取实时的cwd,通过putenv导入环境变量:

myshell维护自己的环境变量:


 

1.我们让子进程执行cd ..命令的时候,为什么我们执行pwd命令的时候,还是和之前一样,路径没有变化?

本质就是,我们更改的是子进程的环境变量pwd,没有改变父进程的。当执行pwd时,这个进程的环境变量还是由父进程来的。而父进程的环境变量没有改变,所以pwd出来的结果也没有改变。

2.环境变量是由shell自己维护的。

3.在这个简易版shell中,我们没有维护这个环境变量,还是依靠系统的环境变量。当环境没有修改,用的还是系统的环境变量,更改时才写时拷贝。

4.echo命令也是内键命令,因为子进程不会继承父进程的本地环境变量。所以要打印本地变量,只有由shell来做。

打印命令行提示符(PrintCommandLine):

启动shell程序,就是创建-bash进程,本质就是一个进程。

首先看到命令行的提示符是这样的:

[kym@hcss-ecs-32c9 2024-11-26]$ 

包括:
1.用户名。2.主机名。3.当前的路径。4.命令行提示符。($)

1.USER和LOGNAME(用户名):

LOGNAME:

USER和LOGNAME都与当前用户有关,但LOGNAME是POSIX标准的一部分,更加标准化和一致,所以更推荐用LOHNAME确定当前的用户的登录身份。

USER:

USER的环境变量可能在某些系统中与LOGNAME有相同的值,但因为其行为不一致,在精确用户身份的时候应该慎用。

2.HOSTNAME和PWD:

通过环境变量获取这些信息。

三个函数获得用户信息(GetLOGNAME),主机信息(GetHOSTNAME),当前路径信息(GetPWD)。

通过string进行传递,如果要谁用c语言的字符串,就通过c_str()进行获得底层char。

头文件:

#include <stdio.h>

函数原型:

int sprintf(char *str, const char *format, ...);
int snprintf(char *str, size_t size, const char *format, ...);

将这些输入到一个字符串中。

  const size_t basesize=1024;//获取用户名信息string GetLOGNAME(){string log_name=getenv("LOGNAME");return log_name.empty()?"None":log_name;}//获取当前主机信息string GetHSOTNAME(){string host_name=getenv("HOSTNAME");return host_name.empty()?"None":host_name;}//获取当前路径信息string GetPWD(){    string pwd=getenv("PWD");    if(pwd.empty())    return "None";    string separator="/";    string sub_str=pwd.substr(pwd.find_last_of(separator)+1);    return sub_str;    }//生成command_line字符串    string MakeCommandLine()                                                                                                                                                                                         {//[kym@hcss-ecs-32c9 2024-11-26]$    char command_line[basesize];    snprintf(command_line,basesize,"[%s@%s %s]@",\GetLOGNAME().c_str(),\    GetHSOTNAME().c_str(),\GetPWD().c_str());return command_line;}// //1.打印命令行提示符void PrintCommandLine(){printf("%s",MakeCommandLine().c_str());fflush(stdout);}

获取命令行信息(GetCommadLine)

bool  GetCommandLine(char command_buff[],size_t size)
{char* result=fgets(command_buff,size,stdin);if(result==NULL)return false;result[strlen(result)-1]=0;return true;
}

读取失败返回false,读取成功把换行符覆盖。 

读取时,处理换行符:

如果我们以一行来读取字符串,那么最会就有换行符,换行符也会读取进来。所以打印的时候,我们没有加换行,也是来到了新的一行。

解决办法:

在返回前,把\n置为0。

result[strlen(result)-1]=0;

解析命令行(ParseCommandLine)

通过strtok函数进行分解字符串。

#include <string.h>

char *strtok(char *str, const char *delim);

bool ParseCommandLine(char command_buff[],int len)    
{    (void)len;    argc=0;     //初始化    memset(argv,0,sizeof(argv));    const char* sep=" ";    argv[argc++]=strtok(command_buff,sep);    while((bool)(argv[argc++]=strtok(nullptr,sep)));    argc--;    return false;    
} 

sep表示分隔符,用来把字符串进行分解。但是在分解之前,我们需要把argc和argv进行初始化。每次执行新的命令。

strtok函数第一次调用的时候,str指向要分割的字符串。在后续的调用中传NULL。因为strtok函数内部有静态变量维护当前字符串的位置。


执行命令(ExecuteCommand)

通过子进程发生程序替换。当id==0,表示子进程。如果发生了程序替换,还执行了原来的exit,就表示发生错误。然后就是父进程子进程。

bool ExecuteCommand()    
{    pid_t id=fork();    if(id<0)    return false;    if(id==0)    {    execvp(argv[0],argv);    exit(1);    }    int status=0;    pid_t rid=waitpid(id,&status,0);    if(rid<0)    {    //等待失败    }    else    {    return true;                                                                                                                                                                                               }    return false;    
}    

哪些命令可以让子进程执行,哪些命令不能让子进程执行?为什么?

让shell去执行的命令,叫做内键命令

当执行cd命令时,为什么pwd没有改变?

我们写的超简易版shell中,让子进程去执行cd .. 。但是其他的进程不是由子进程产生的,不会继承子进程的环境变量,还是去继承父进程的环境变量。虽然在子进程中改了环境变量,但是没有得到进程,所以不起作用。在真正的shell中,就是要去改变shell的环境变量。因为其他的进程都是bash的子进程。


通过getcwd获取实时的cwd,通过putenv导入环境变量:

//获取当前路径信息
string GetPWD()
{if(nullptr==getcwd(cwd,sizeof(cwd)))return "None";snprintf(pwdenv,sizeof(pwdenv),"PWD=%s",cwd);//更新envputenv(pwdenv);return cwd;
}

myshell维护自己的环境变量:

环境变量和本地变量是存在于shell中的一个表。这两张表就是全局的char*数组。指向很多的字符串。后序我们碰见要导入环境变量的命令,我们直接在shell中的genv数组指向一个堆空间,然后把第一个为空的数组指向这个字符串。

为什么要新申请空间,然后拷贝,再指向?

因为我们每执行一个命令,argv都是会变化的。如果我们直接让genv的元素指向argv的元素,以后会发生变化。这样环境变量就找不到了。

相关文章:

【Linux课程学习】:《简易版shell实现和原理》 《哪些命令可以让子进程执行,哪些命令让shell执行(内键命令)?为什么?》

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;Linux课程学习 &#x1f337;追光的人&#xff0c;终会万丈光芒 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 打印命令行提示符&#xff08;PrintCommandLin…...

2024年11月27日Github流行趋势

项目名称&#xff1a;screenshot-to-code 项目维护者&#xff1a;abi clean99 sweep-ai kachbit vagusX项目介绍&#xff1a;通过上传截图将其转换为整洁的代码&#xff08;支持HTML/Tailwind/React/Vue&#xff09;。项目star数&#xff1a;62,429项目fork数&#xff1a;7,614…...

Java中的线程池使用详解

文章目录 Java中的线程池使用详解一、引言二、线程池的创建与使用1、线程池的创建1.1、FixedThreadPool&#xff08;固定大小线程池&#xff09;1.2、CachedThreadPool&#xff08;可缓存线程池&#xff09;1.3、SingleThreadExecutor&#xff08;单线程化线程池&#xff09;1.…...

Redis(概念、IO模型、多路选择算法、安装和启停)

一、概念 关系型数据库是典型的行存储数据库&#xff0c;存在的问题是&#xff0c;按行存储的数据在物理层面占用的是连续存储空间&#xff0c;不适合海量数据存储。 Redis在生产中使用的最多的是用作数据缓存。 服务器先在缓存中查询数据&#xff0c;查到则返回&#xff0c;…...

计算机网络 第4章 网络层

计算机网络 &#xff08;第八版&#xff09;谢希仁 第 4 章 网络层4.2.2 IP地址**无分类编址CIDR**IP地址的特点 4.2.3 IP地址与MAC地址4.2.4 ARP 地址解析协议4.2.5 IP数据报的格式题目2&#xff1a;IP数据报分片与重组题目&#xff1a;计算IP数据报的首部校验和(不正确未改) …...

Java学习笔记--继承方法的重写介绍,重写方法的注意事项,方法重写的使用场景,super和this

目录 一&#xff0c;方法的重写 二&#xff0c;重写方法的注意事项 三&#xff0c;方法重写的使用场景 四&#xff0c;super和this 1.继承中构造方法的特点 2.super和this的具体使用 super的具体使用 this的具体使用 一&#xff0c;方法的重写 1.概述:子类中有一个和父类…...

高级java每日一道面试题-2024年11月27日-JVM篇-JVM的永久代中会发生垃圾回收么?

如果有遗漏,评论区告诉我进行补充 面试官: JVM的永久代中会发生垃圾回收么? 我回答: 在Java虚拟机&#xff08;JVM&#xff09;的历史版本中&#xff0c;确实存在一个称为“永久代”&#xff08;Permanent Generation, 或者简称PermGen&#xff09;的内存区域。永久代主要用…...

Spring Boot教程之十: 使用 Spring Boot 实现从数据库动态下拉列表

使用 Spring Boot 实现从数据库动态下拉列表 动态下拉列表&#xff08;或依赖下拉列表&#xff09;的概念令人兴奋&#xff0c;但编写起来却颇具挑战性。动态下拉列表意味着一个下拉列表中的值依赖于前一个下拉列表中选择的值。一个简单的例子是三个下拉框&#xff0c;分别显示…...

基于混合ABC和A*算法复现

基于混合ABC和A*算法复现 一、背景介绍二、算法原理&#xff08;一&#xff09;A*算法原理&#xff08;二&#xff09;人工蜂群算法原理&#xff08;三&#xff09;混合ABC和A*算法策略 三、代码实现&#xff08;一&#xff09;数据准备&#xff08;二&#xff09;关键函数实现…...

狂野飙车8+(Asphalt 8+) for Mac 赛车竞速游戏 安装教程

Mac分享吧 文章目录 狂野飙车8(Asphalt 8) for Mac 赛车竞速游戏软件 效果图展示一、狂野飙车8(Asphalt 8) 赛车竞速游戏 Mac电脑版——v2.1.11️⃣&#xff1a;下载软件2️⃣&#xff1a;安装软件2.1 左侧安装包拖入右侧文件夹中&#xff0c;等待安装完成&#xff0c;运行软件…...

网络技术-VRRP(虚拟路由冗余协议)部署介绍

一、VRRP的含义 VRRP&#xff08;Virtual Router Redundancy Protocol&#xff0c;虚拟路由冗余协议&#xff09;是一种高度可靠的路由器备用协议&#xff0c;用于在局域网内部提供路由器冗余。 其部署方式主要是通过多个路由器组成一个虚拟路由器组&#xff0c;通过协议选…...

C语言解决空瓶换水问题:高效算法与实现

标题&#xff1a;C语言解决空瓶换水问题&#xff1a;高效算法与实现 一、问题描述 在一个饮料促销活动中&#xff0c;你可以通过空瓶换水的方式免费获得更多的水&#xff1a;3个空瓶可以换1瓶水。喝完这瓶水后&#xff0c;空瓶会再次变为空瓶。假设你最初拥有一定数量的空瓶&a…...

day2全局注册

全局注册代码&#xff1a; //文件核心作用&#xff1a;导入App.vue,基于App.vue创建结构渲染index.htmlimport Vue from vue import App from ./App.vue //编写导入的代码&#xff0c;往代码的顶部编写&#xff08;规范&#xff09; import HmButton from ./components/Hm-But…...

鸿蒙多线程应用-taskPool

并发模型 并发模型是用来实现不同应用场景中并发任务的编程模型&#xff0c;常见的并发模型分为基于内存共享的并发模型和基于消息通信的并发模型。 Actor并发模型作为基于消息通信并发模型的典型代表&#xff0c;不需要开发者去面对锁带来的一系列复杂偶发的问题&#xff0c;同…...

【失败经验】将算法模型封装为安卓应用

背景&#xff1a;不懂安卓开发&#xff0c;希望能使用大模型编码完成安卓应用生成&#xff0c;调用算法模型进行预测。 模型准备&#xff1a; pip方案安装pcnn&#xff1b; 然后需要将pytorch训练完成的算法模型保存为torchscript模型&#xff0c;然后使用pcnn转换为ncnn的模…...

ABAP OOALV模板

自用模板&#xff0c;可能存在问题 一、主程序 *&---------------------------------------------------------------------* *& Report ZVIA_OO_ALV *&---------------------------------------------------------------------* REPORT ZVIA_OO_ALV.INCLUDE ZVI…...

YOLOv8-ultralytics-8.2.103部分代码阅读笔记-autobatch.py

autobatch.py ultralytics\utils\autobatch.py 目录 autobatch.py 1.所需的库和模块 2.def check_train_batch_size(model, imgsz640, ampTrue, batch-1): 3.def autobatch(model, imgsz640, fraction0.60, batch_sizeDEFAULT_CFG.batch): 1.所需的库和模块 # Ultraly…...

SycoTec 4060 ER-S德国高精密主轴电机如何支持模具的自动化加工?

SycoTec 4060 ER-S高速电主轴在模具自动化加工中的支持体现在以下几个关键方面&#xff1a; 1.高精度与稳定性&#xff1a;SycoTec 4060 ER-S锥面跳动小于1微米&#xff0c;确保了加工过程中的极高精度&#xff0c;这对于模具的复杂几何形状和严格公差要求至关重要。高精度加工…...

部署 DeepSpeed以推理 defog/sqlcoder-70b-alpha 模型

部署 DeepSpeed 以推理 defog/sqlcoder-70b-alpha 这样的 70B 模型是一个复杂的过程&#xff0c;涉及多个关键步骤。下面是详细的步骤&#xff0c;涵盖了从模型加载、内存优化到加速推理的全过程。 1. 准备环境 确保你的环境配置正确&#xff0c;以便能够顺利部署 defog/sqlc…...

Python网络爬虫基础

Python网络爬虫是一种自动化工具&#xff0c;用于从互联网上抓取信息。它通过模拟人类浏览网页的行为&#xff0c;自动地访问网站并提取所需的数据。网络爬虫在数据挖掘、搜索引擎优化、市场研究等多个领域都有广泛的应用。以下是Python网络爬虫的一些基本概念&#xff1a; 1.…...

OpenMPI进程绑定实战:如何用--bind-to和--map-by提升HPC应用性能(附Slurm配置示例)

OpenMPI进程绑定实战&#xff1a;NUMA架构下的性能优化与Slurm集成指南 1. 高性能计算中的进程绑定核心原理 在现代高性能计算环境中&#xff0c;CPU核心绑定技术已成为提升并行计算效率的关键手段。当我们在双路CPU服务器上运行计算密集型应用时&#xff0c;经常会遇到"一…...

别再一上来就搞ETL了!聊聊我们团队在数据治理项目里踩过的第一个坑:数据资产划分

数据治理第一步&#xff1a;为什么跳过资产划分会让你的ETL工程翻车&#xff1f; 凌晨三点的办公室&#xff0c;咖啡杯已经见底&#xff0c;ETL管道却因为数据源混乱再次报错——这是许多数据团队的真实噩梦。我们团队在去年启动企业级数据治理项目时&#xff0c;也曾陷入"…...

告别SD卡!手把手教你用Vitis 2020.2把ZYNQ程序烧进QSPI Flash,实现上电自启动

从开发到量产&#xff1a;ZYNQ QSPI Flash程序固化全流程实战指南 在嵌入式系统开发中&#xff0c;从原型验证到产品量产往往需要跨越一道关键的技术门槛——程序固化。对于使用Xilinx ZYNQ系列芯片的开发者而言&#xff0c;如何将调试阶段依赖SD卡运行的程序&#xff0c;可靠地…...

Python实战:温度转换小工具开发(附GESP考试真题解析)

Python实战&#xff1a;温度转换小工具开发与GESP考试技巧精讲 温度转换是编程入门阶段的经典案例&#xff0c;也是GESP考试中常见的题型。本文将从零开始构建一个功能完整的温度转换工具&#xff0c;同时深入解析GESP考试中可能遇到的类似题型&#xff0c;帮助初学者掌握Pytho…...

macOS歌词解决方案:LyricsX从安装到精通的全方位指南

macOS歌词解决方案&#xff1a;LyricsX从安装到精通的全方位指南 【免费下载链接】LyricsX &#x1f3b6; Ultimate lyrics app for macOS. 项目地址: https://gitcode.com/gh_mirrors/ly/LyricsX 在数字音乐体验中&#xff0c;歌词同步显示是提升沉浸感的关键要素。然而…...

OpenClaw+GLM-4.7-Flash:学术论文辅助写作全流程

OpenClawGLM-4.7-Flash&#xff1a;学术论文辅助写作全流程 1. 为什么需要AI辅助学术写作 作为一名经常需要撰写学术论文的研究者&#xff0c;我深刻体会到写作过程中的痛点。从海量文献中筛选关键信息、整理参考文献格式、反复修改论文结构&#xff0c;这些工作往往耗费大量…...

基于Qwen-2.5-VL与RAG的智能客服系统实战:从微调优化到生产部署

最近在做一个智能客服项目&#xff0c;客户那边对回答的准确性和时效性要求特别高。传统的规则引擎早就力不从心了&#xff0c;而直接用通用大模型&#xff0c;又经常“一本正经地胡说八道”&#xff0c;或者回答一些过时的信息。经过一番折腾&#xff0c;我们最终选择了 Qwen-…...

突破局限:开源微信插件WeChatExtension-ForMac革新体验全解析

突破局限&#xff1a;开源微信插件WeChatExtension-ForMac革新体验全解析 【免费下载链接】WeChatExtension-ForMac Mac微信功能拓展/微信插件/微信小助手(A plugin for Mac WeChat) 项目地址: https://gitcode.com/gh_mirrors/we/WeChatExtension-ForMac 作为Mac用户&a…...

交互式社会工程学攻击的演进与防御:基于2025年语音钓鱼激增现象的深度分析

摘要 随着人工智能生成内容&#xff08;AIGC&#xff09;技术的成熟与普及&#xff0c;网络攻击的初始访问向量正经历从自动化、非交互式向高度个性化、实时交互式的范式转变。本文基于Google Cloud Mandiant发布的《M-Trends 2026》报告数据&#xff0c;深入剖析了2025年语音钓…...

Qwen3-0.6B-FP8效果展示:用‘把这篇技术博客改写成适合小学生理解的版本’实测简化能力

Qwen3-0.6B-FP8效果展示&#xff1a;用‘把这篇技术博客改写成适合小学生理解的版本’实测简化能力 1. 引言&#xff1a;当大模型遇上“小学生”挑战 想象一下&#xff0c;你面前有一篇满是专业术语、复杂逻辑的技术文章&#xff0c;现在需要把它讲给一个小学三年级的孩子听&…...