简单shell
目录
预备知识
fork
进程等待
wait
waitpid
环境变量
概念
分类
常见的环境变量及其用途
环境变量的查看与设置
exec系列
函数解释
命名理解
简单shell
预备知识
fork
fork 是 Linux 和许多其他类 Unix 系统中的一个重要系统调用,它用于创建一个新的进程,这个新进程是当前进程的复制品,称为子进程。子进程会获得父进程当前状态的副本,包括父进程的内存布局、环境变量、打开的文件描述符等。但是,子进程和父进程是两个独立的执行线程,它们可以独立地运行程序的不同部分。
以下是关于 fork 的一些关键点:
- 复制:子进程是父进程的一个副本。但是,这种复制是“写时复制”(Copy-On-Write, COW)的。这意味着,如果子进程和父进程都不修改它们共享的内存区域,那么这些区域实际上不会被复制,从而节省内存和 CPU 时间。
- 返回值:fork系统调用在父进程中返回新创建的子进程的进程 ID(PID),而在子进程中返回 0。这是区分父进程和子进程的一个常用方法。
- 资源分配:子进程会获得其父进程所拥有资源的副本,如文件描述符、环境变量等。但是,这些资源并不一定是物理上独立的;它们通常是通过引用计数或其他机制来共享的。
- 并发:由于子进程和父进程是两个独立的执行线程,因此它们可以并发地执行不同的任务。这使得 fork成为实现多进程并发和并行处理的重要工具。
- 进程间通信:由于子进程和父进程是独立的,因此它们之间需要进行通信以共享数据或协调行为。这可以通过各种进程间通信(IPC)机制来实现,如管道、消息队列、信号量、共享内存等。
- 终止和等待:当子进程终止时,它会留下一个僵尸进程(Zombie Process),直到其父进程调用 wait或waitpid系统调用来获取其终止状态并释放其占用的资源。
需要注意的是,虽然 fork 是一个强大的工具,但它也有一些限制和开销。例如,由于需要复制父进程的状态,因此 fork 的开销通常比创建线程要大。此外,由于子进程和父进程是独立的,因此它们之间的通信和同步也需要额外的开销和复杂性。因此,在选择使用 fork 还是其他并发机制(如线程或协程)时,需要根据具体的应用场景和需求进行权衡。
进程等待
wait
- 功能:wait函数用于使父进程等待其任意一个子进程结束,并回收该子进程的资源。当子进程结束时,内核会向父进程发送SIGCHLD信号,父进程可以通过wait函数来响应这个信号并获取子进程的状态。
- 函数原型:pid_t wait(int *wstatus);- 参数wstatus是一个指向整数的指针,用于存储子进程的退出状态。如果父进程不关心子进程的退出状态,可以将此参数设为NULL。
- 返回值是已结束子进程的进程ID(PID),如果出现错误则返回-1。
 
- 参数
- 特点:wait函数会阻塞父进程的执行,直到有一个子进程结束。如果调用wait时子进程已经结束,则wait会立即返回子进程的结束状态值。
waitpid
- 函数原型:#include #include pid_t wait(int*status); 返回值: 成功返回被等待进程pid,失败返回-1
- 返回值: - 当正常返回的时候waitpid返回收集到的子进程的进程ID;
- 如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0;
- 如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在;
 
- 参数: - pid: - Pid=-1,等待任一个子进程。与wait等效。
- Pid>0.等待其进程ID与pid相等的子进程。
 
- status: - WIFEXITED(status): 若为正常终止子进程返回的状态,则为真。(查看进程是否是正常退出)
- WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。(查看进程的退出码)
 
- options: - WNOHANG: 若pid指定的子进程没有结束,则waitpid()函数返回0,不予以等待。若正常结束,则返回该子进 程的ID。
 
 
- pid: 
环境变量
概念
- 定义:环境变量是系统预定义的参数,相当于全局变量,存在于所有的shell中,具有继承性。它们可存储有关shell会话和工作环境的信息。
- 作用:环境变量允许在内存中存储数据,以便运行在shell上的程序和脚本访问。这些数据可以用来识别用户、系统、Shell的特性以及任何其它需要存储的数据。
分类
- 按作用范围分: - 系统环境变量:公共的,对全部的用户都生效。
- 用户环境变量:用户私有的、自定义的个性化设置,只对该用户生效。
 
- 按生存周期分: - 永久环境变量:在环境变量脚本文件中配置,用户每次登录时会自动执行这些脚本,相当于永久生效。
- 临时环境变量:使用时在Shell中临时定义,退出Shell后失效。
 
常见的环境变量及其用途
- PATH:指定命令的搜索路径,由冒号分隔的目录列表,用于告诉系统在哪里可以找到可执行文件。
- HOME:指定用户的主工作目录,即用户登录到Linux系统时,默认的目录。
- SHELL:当前Shell的路径,通常指向用户当前使用的shell解析器,如/bin/bash。
- LD_LIBRARY_PATH:C/C++语言动态链接库文件搜索的目录,对C/C++程序员来说非常重要。
- CLASSPATH:JAVA语言库文件搜索的目录,对JAVA程序员来说非常重要。
环境变量的查看与设置
- 查看: - 使用env命令可以查看当前用户全部的环境变量。
- 使用echo $环境变量名可以查看特定环境变量的值。
 
- 使用
- 设置: - 使用export命令可以设置新的环境变量或修改现有环境变量的值。例如,export PATH=$PATH:/new/directory。
- 如果希望环境变量永久生效,需要在登录脚本文件中(如/etc/profile、/etc/profile.d/、~/.bash_profile、~/.bashrc等)进行配置
 
- 使用
exec系列
#include <unistd.h>
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
nt execle(const char *path, const char *arg, ...,char *const envp[]);
int execv(const char *path, char *const argv[]); i
nt execvp(const char *file, char *const argv[]);
int execve(const char *path, char *const argv[], char *const envp[]);
这些函数的主要目的是在当前进程的上下文中执行一个新程序,从而替换当前进程的映像。它们允许程序在运行时加载新的可执行文件,实现动态性和灵活性。
函数解释
- 这些函数如果调用成功则加载新的程序从启动代码开始执行,不再返回。
- 如果调用出错则返回-1
- 所以exec函数只有出错的返回值而没有成功的返回值
命名理解
- l(list) : 表示参数采用列表
- v(vector) : 参数用数组
- p(path) : 有p自动搜索环境变量PATH
- e(env) : 表示自己维护环境变量
简单shell
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#include<unistd.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#define SIZE 512
#define ZERO '\0'
#define SEP " "
#define NUM 32
#define SkipPath(p) do{p+=strlen(p)-1;while(*p!='/')p--;}while(0)
#define SkipSpace(cmd,pos) do{ \while(1){\if(isspace(cmd[pos]))\pos++;\else break;\}}while(0)
#define none_type 0
#define in_type 1
#define out_type 2
#define app_type 3
int redir_type=none_type;
char* filename=NULL;char* gArgv[NUM];
int lastcode=0;
void Die()
{exit(1);
}
const char* GetHostname()
{const char* hostname=getenv("HOSTNAME");if(hostname==NULL)return "/";return hostname;
}
const char* GetUsername()
{const char* user=getenv("USER");if(user==NULL)return "none";return user;
}
const char* Getcwd()
{const char* cwd=getenv("PWD");if(cwd==NULL) return "none";return cwd;
}
void MakeCommmandLine()
{char line[SIZE];const char* hostname=GetHostname();const char* username=GetUsername();const char* cwd=Getcwd();SkipPath(cwd);snprintf(line,sizeof(line),"[%s@%s %s]> ",username,hostname,strlen(cwd)==1?"/":cwd+1);printf("%s",line);fflush(stdout);
}
int GetUserCommad(char commad[],size_t n)
{char* s=fgets(commad,n,stdin);if(s==NULL)return -1;commad[strlen(commad)-1]=ZERO;return strlen(commad);}
void CheckRedir(char cmd[])
{int pos=0;int end=strlen(cmd);while(pos<end){if(cmd[pos]=='>'){if(cmd[pos+1]=='>'){cmd[pos++]=0;pos++;redir_type=app_type;SkipSpace(cmd,pos);filename=cmd+pos;}else {cmd[pos++]=0;redir_type=out_type;SkipSpace(cmd,pos);filename=cmd+pos;  }}else if(cmd[pos]=='<'){cmd[pos++]=0;redir_type=in_type;SkipSpace(cmd,pos);filename=cmd+pos;}else{pos++;}}
}
void SplitCommad(char command[])
{gArgv[0]=strtok(command,SEP);int index=1;while((gArgv[index++]=strtok(NULL,SEP)));
}
void ExecuteCommand()
{pid_t id=fork();if(id<0)Die();else if (id==0){//子进程if(filename!=NULL){if(redir_type==in_type){int fd=open(filename,O_RDONLY);dup2(fd,0);}else if (redir_type==out_type){int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);dup2(fd, 1); }else if (redir_type==app_type){int fd = open(filename, O_WRONLY | O_CREAT | O_APPEND, 0666);dup2(fd, 1);}}execvp(gArgv[0],gArgv);exit(errno);}else{//父进程int status = 0;pid_t rid = waitpid(id, &status, 0);if(rid > 0){lastcode = WEXITSTATUS(status);if(lastcode != 0) printf("%s:%s:%d\n", gArgv[0], strerror(lastcode), lastcode);} }
}
int main()
{int quit=0;while(!quit){redir_type=none_type;filename=NULL;//创建一个自己的命令行MakeCommmandLine();//获取用户命令char usercommad[SIZE];int n=GetUserCommad(usercommad,sizeof(usercommad));if(n<=0)return 1;CheckRedir(usercommad);//测试一下//   printf("cmd: %s\n", usercommad);//   printf("redir: %d\n", redir_type);//   printf("filename: %s\n", filename);//分割字符串SplitCommad(usercommad);//执行命令ExecuteCommand();}return 0;
}
相关文章:
简单shell
目录 预备知识 fork 进程等待 wait waitpid 环境变量 概念 分类 常见的环境变量及其用途 环境变量的查看与设置 exec系列 函数解释 命名理解 简单shell 预备知识 fork fork 是 Linux 和许多其他类 Unix 系统中的一个重要系统调用,它用于创建一个新的…...
Spring Boot + FreeMarker 实现动态Word文档导出
Spring Boot FreeMarker 实现动态Word文档导出 在现代企业应用中,文档自动化生成是一项提升工作效率的重要功能。Spring Boot与FreeMarker的组合,为开发者提供了一个强大的平台,可以轻松实现动态Word文档的导出。本文将指导你如何使用Sprin…...
 
3D生物打印的未来:多材料技术的突破
多材料生物打印技术是近年来发展迅速的一项技术,为组织工程和再生医学带来了新的机遇,可以帮助我们更好地理解人体组织的结构和功能,并开发新的治疗方法。 1. 组织构建 复杂性模拟:多材料生物打印技术能够构建具有层次结构和异质…...
 
充电宝口碑哪个好?好用充电宝品牌有哪些?好用充电宝推荐
充电宝作为我们日常生活和出行的重要伙伴,其品质和性能直接影响着我们的使用体验。今天,就来和大家探讨一下充电宝口碑哪个好,为大家盘点那些备受赞誉的好用充电宝品牌,并向您推荐几款值得入手的充电宝,外出时不再担心…...
Pytorch-----(6)
一 、问题 如何计算基于不同变量的操作如矩阵乘法。 二、具体实现 0.4版本以前,张量是包裹在变量之中的,后者有三个属性grad、volatile和 requires_grad属性。(grad 就是梯度属性,requires_grad属性就是 是否需要存储梯度&#x…...
leetcode hot100 第三题:最长连续序列(Java)
给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。 请你设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例 1: 输入:nums [100,4,200,1,3,2] 输出:4 解…...
 
利用Jaspar进行转录因子结合位点预测
前期我们介绍了如何进行ChIP-qPCR验证,里面提到了一个比较重要的因素——扩增范围的选择及引物的设计。相比双荧光素酶、酵母单杂-点对点验证等允许完整启动子验证的实验,ChIP-qPCR要求单次验证的范围尽量控制在150-200bp内。但一个基因的启动子一般有2-…...
Ubuntu添加系统字体
(2024.6.30) 系统字体保存路径在/usr/share/fonts下,如果此目录下缺少字体,则使用其他可视化api(如Python的pygame库)的默认配置时可能会出现乱码问题。 往Ubuntu中添加字体的方法 方法一:手…...
深度学习相关概念及术语总结2
目录 76.AUC77.DBSCAN聚类78.贝叶斯个性化排序79.BPRBandit算法 76.AUC AUC(Area Under the Curve)是一种常用的评价指标,用于衡量分类模型的性能。AUC值代表了模型在不同阈值下的真阳性率(True Positive Rate)和假阳…...
 
基于改进滑模、经典滑模、最优滑模控制的永磁同步电机调速系统MATLAB仿真
微❤关注“电气仔推送”获得资料(专享优惠) 模型简介 针对永磁同步电机调速系统的响应性能和抗干扰能力问题,本文做了四个仿真,分别为:永磁同步电机的PID控制调速系统、基于传统滑模控制的永磁同步电机的调速系统、最…...
 
windows环境下创建python虚拟环境
windows环境下创建python虚拟环境 使用virtualenv库创建虚拟环境,可使不同的项目处于不同的环境中 安装方法: pip install virtualenv -i https://pypi.tuna.tsinghua.edu.cn/simple pip install virtualenvwrapper-win -i https://pypi.tuna.tsinghua…...
Fragment切换没变化?解决办法在这里
大家好,今天跟大家分享下如何避免fragment切换失败。方法其实很简单,只要在onCreate方法中初始化一个默认的fragment即可。 //开始事务FragmentTransaction transaction getActivity().getSupportFragmentManager().beginTransaction();transaction.rep…...
 
Linux系统防火墙iptables(下)
备份与还原iptables规则设置 1、yum -y install iptables iptables-services 安装iptables软件包 2、systemctl start iptables.service 开启服务 3、systemctl enable iptables.service 开机自启 我们对iptables命令行中的设置,都是临时设置,只要遇到服…...
 
你需要精益管理咨询公司的N+1个理由
近年来,精益管理作为一种被全球众多知名企业验证过的成功管理模式,越来越受到企业的青睐。但是,为何在实施精益管理的过程中,众多企业纷纷选择请咨询公司来协助呢?今天,我们就来一起揭秘这背后的原因。 1. …...
[机器学习]-3 万字话清从传统神经网络到深度学习
神经网络(Neural Networks, NNs)是机器学习的一种重要方法,灵感来源于生物神经系统,由大量互联的节点(称为神经元或单元)组成,通过调整这些节点间的连接权重来学习和表示复杂的非线性关系。传统…...
 
网络安全等级保护2.0(等保2.0)全面解析
一、等保2.0的定义和背景 网络安全等级保护2.0(简称“等保2.0”)是我国网络安全领域的基本制度、基本策略、基本方法。它是在《中华人民共和国网络安全法》指导下,对我国网络安全等级保护制度进行的重大升级。等保2.0的发布与实施,…...
 
用Lobe Chat部署本地化, 搭建AI聊天机器人
Lobe Chat可以关联多个模型,可以调用外部OpenAI, gemini,通义千问等, 也可以关联内部本地大模型Ollama, 可以当作聊天对话框消息框来集成使用 安装方法参考: https://github.com/lobehub/lobe-chat https://lobehub.com/zh/docs/self-hosting/platform/…...
 
基于ARM的通用的Qt移植思路
文章目录 实验环境介绍一、确认Qt版本二、确认交叉编译工具链三、配置Qt3.1、修改qmake.conf3.2、创建autoConfig.sh配置文件 四、编译安装Qt五、移植Qt安装目录六、配置Qt creator6.1、配置qmake6.2、配置GCC编译器6.3、配置G编译器6.4、配置编译器套件6.5、创建应用 七、总结…...
 
IT专业入门,高考假期预习指南
七月来临,各省高考分数已揭榜完成。而高考的完结并不意味着学习的结束,而是新旅程的开始。对于有志于踏入IT领域的高考少年们,这个假期是开启探索IT世界的绝佳时机。 一、基础课程预习指南 IT专业是一个广泛的领域,涵盖了从软件开…...
芯片详解——AD7606C
芯片详解——AD7606C AD7607C 是一款由 Analog Devices(模拟器件公司)生产的 6 通道同步采样模数转换器(ADC),适用于高速数据采集系统。 工作原理 AD7607C 的工作原理主要包括以下几个步骤: 模拟信号输入:AD7607C 有六个模拟输入通道,可以同时进行采样。这些模拟信号…...
 
ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...
 
SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
 
海云安高敏捷信创白盒SCAP入选《中国网络安全细分领域产品名录》
近日,嘶吼安全产业研究院发布《中国网络安全细分领域产品名录》,海云安高敏捷信创白盒(SCAP)成功入选软件供应链安全领域产品名录。 在数字化转型加速的今天,网络安全已成为企业生存与发展的核心基石,为了解…...
 
【笔记】AI Agent 项目 SUNA 部署 之 Docker 构建记录
#工作记录 构建过程记录 Microsoft Windows [Version 10.0.27871.1000] (c) Microsoft Corporation. All rights reserved.(suna-py3.12) F:\PythonProjects\suna>python setup.py --admin███████╗██╗ ██╗███╗ ██╗ █████╗ ██╔════╝…...
 
2025-06-01-Hive 技术及应用介绍
Hive 技术及应用介绍 参考资料 Hive 技术原理Hive 架构及应用介绍Hive - 小海哥哥 de - 博客园https://cwiki.apache.org/confluence/display/Hive/Home(官方文档) Apache Hive 是基于 Hadoop 构建的数据仓库工具,它为海量结构化数据提供类 SQL 的查询能力…...
 
Appium+python自动化(八)- 认识Appium- 下章
1、界面认识 在之前安装appium的时候说过我们有两种方法安装,也就有两种结果,一种是有界面的(客户端安装),一种是没有界面的(终端安装),首先我们先讲一下有界面的,以及界…...
 
【JMeter】后置处理器 - 提取器
文章目录 概览边界提取器正则提取器JSON提取器 概览 CSS/JQuery提取器;给网页使用JSON提取器:给JSON数据使用★边界提取器:给字符串使用★正则表达式提取器:更加高级的字符使用★Xpath提取器:给网页使用 边界提取器…...
 
【Linux】centos软件安装
目录 Linux下安装软件的办法什么是yum使用yum试着安装软件查看yum源配置额外的第三方库 Linux下安装软件的办法 做为一个操作系统,与win和mac一样,安装软件无可厚非。那Linux下安装软件有哪些办法呢?第一种是直接下载源代码本地编译安装&…...
Kali Linux 安全工具解析
Kali Linux 安全工具解析 目录 Kali Linux 安全工具解析一、Kali Linux 概述1.1 核心特性1.2 系统要求 二、核心工具分类与实战应用2.1 信息收集工具2.1.1 Nmap2.1.2 Recon-ng2.1.3 theHarvester 2.2 漏洞利用工具2.2.1 Metasploit Framework2.2.2 SQLMap2.2.3 Burp Suite 2.3 …...
