环境变量和进程地址空间
目录
环境变量:
env:显示所有的环境变量:
echo +$环境变量名表示查看环境变量的值
理解环境变量:
getenv:显示环境变量的值
export
set命令:显示所有变量
unset取消变量:
pwd:当前路径
自主实现pwd环境变量:
问题:环境变量是怎么被子进程继承的(思考题目)
命令行参数:
main函数的第三个参数:
environ
putenv
stat
我们提出一个问题:
现象:
现象:
echo的问题:
程序地址空间
感性理解虚拟地址空间
操作系统如何画饼呢?
环境变量:
一般是指在 操作系统 中用来指定操作系统运行环境的一些参数
我们使用指令来具体理解环境变量。
env:显示所有的环境变量:
这就是所有的环境变量。
echo +$环境变量名表示查看环境变量的值
例如:
PATH上一节课我们已经讲过,PATH是一个环境变量,它的值等于Linux系统指令所在的路径。
我们再举几个例子:
假如我们想要显示家目录:
假如我们想要显示登录账户的名字:
理解环境变量:
我们输入指令env,显示所有的环境变量:
我们可以在这些环境变量中找到名字为USER的环境变量:
这里表示当前登录的用户名。
接下来,我们切换到root用户:
我们输入env指令:
当我们切换用户的时候,我们的USER环境变量发生了变化。
环境变量是可以随着我们运行环境的变化而发生更改的。
接下来,我们写一串代码帮助理解:
我们首先创建一个源文件
我们再写出mycmd.c的源文件对应的解决方案文件Makefile
我们使用vim对Makefile进行文本编辑:
我们对这串指令进行分析:
表示mycmd的依赖对象是mycmd.c
这是对应的依赖方法:gcc表示我们要进行编译 -o表示我们要进行编译链接形成可执行程序,$@表示左依赖列表,也就是mycmd,@^表示的是右依赖列表,也就是mycmd.c,表示我们要把mycmd.c经过编译链接形成对应的可执行程序mycmd
.PHONY有两层含义:含义1表示我们的clean是一个为目标,没有对应的依赖对象,含义2:.PHONY修饰的目标不会关心文件的修改时间,总是被执行,clean对应的依赖方法是强制删除文件mycmd.c
getenv:显示环境变量的值
该函数的返回值列表如图:
我们举一个例子:
我们通过echo得到了环境变量USER的值,我们通过getenv函数也能得到相同的结果。
我们对mycmd.c源文件进行文本编辑:
我们调用getenv函数,函数的参数是字符串"USER",char*类型的who用来接收返回时,然后我们以字符串的形式打印who
我们输入make,默认执行的是Makefile的第一个解决方法:
接下来,我们通过./mycmd来调用该程序:
所以我们的who指向的bbb,我们可以得出结论:
getenv函数的作用:
name是环境变量的名字,返回的结果是环境变量的值,假如调用失败时,我们返回空指针。
接下来,我们切换到用户root
我们调用该可执行程序:
我们并没有对mycmd.c的源文件的文本进行修改,但是USER发生了变化,所以我们打印的结果也就发生了变化。
所以这里的USER环境变量的作用就是标识当前使用的Linux用户。
我们再切换会原来的bbb用户
对mycmd.c进行文本修改:
我们调用strcmp,假如who等于root时,我们显示用户名,陷入who不是root时,我们提示权限不足。
我们当前的账户名为bbb
我们make之后调用该可执行程序:
显示我们权限不足,我们切换成为root用户:
所以我们可以通过判定环境变量USER的值来决定那些用户有权限,而哪些用户没有权限。
这里的环境变量起到了身份认证的作用,当我们想要执行一个操作时,我们先检测环境变量USER的值,假如USER拥有这个权限,我们再执行这个操作。
所以sudo的本质就是相当于把我们的环境变量USER的值由原来的bbb切换成为root。
我们也可以自己设置一些环境变量,例如:
我们设置变量myval的值为1234
我们调用echo
我们显示了该变量的值,接下来,我们调用env,从env中找这个myval的变量。
我们并没有找到myval的值,原因是什么?
原因是env显示的是所有的环境变量,而echo既可以显示普通的变量,也可以显示环境变量,我们这里的myval很明显是一个普通变量,所以env无法显示。
我们可以把这里的myval理解为局部变量,把env显示的环境变量理解为全局变量。
那我们该如何链接环境变量的全局性和这个局部变量呢?
我们进行解释:
首先对mycmd.c进行文本编辑。
我们调用getenv函数 看是否能够得到myenv的值。
所以myval值并不是一个环境变量。
接下来,我们介绍export指令
export
export的作用是定义环境变量;假如一个变量已经存在,export+该变量能够将该变量导成环境变量。
例如:
我们把myval导成环境变量。
这个时候,在env中就能找到该环境变量了。
接下来我们调用mycmd,因为我们的myval变量变成了全局变量。
所以可以显示该变量的值。
重点:bash是一个系统进程,在该进程内部我们创建了环境变量和普通变量,mycmd是bash创建的子进程,子进程可以继承父进程的环境变量,但是无法继承普通变量,所以环境变量具有全局属性,我们有了环境变量,就可以做身份识别,查找指令路径等工作了
本地变量只在bash进程中有效,无法在被子进程mycmd继承。
set命令:显示所有变量
我们创建一个本地变量,我们通过env无法显示,这个时候,我们可以使用set命令
set既显示所有的环境变量,也显示所有的本地变量
假如我们想要把youval导成环境变量,我们可以用export
unset取消变量:
set和env都找不到这个变量。
export定义环境变量的写法:
pwd:当前路径
我们提出一个问题:
为什么我们可以调用这个指令?
我们知道,ls是系统给的指令,环境变量PATH中对应的就是系统路径,所以我们知道路径,就可以直接调用该指令,但是mycmd呢?我们知道,调用一个指令要么知道绝对路径,要么知道相对路径,最标准的写法应该是这样:
因为我们有环境变量PWD
我们输入env查看环境变量。
我们可以找到环境变量PWD
这里表示的就是当前路径,因为我们的ls是bash的子进程,子进程继承了父进程的环境变量,也就继承了PWD,所以我们知道了当前的路径,所以我们可以这样写:
我们退到上级目录:
环境变量PWD也发生了改变。
原因:环境变量是在bash中维护,当当前路径发生改变时,bash就会修改环境变量PWD的值。
所以这里实质的原因是:ls也是一个进程,是bash的子进程,PWD是bash的环境变量,环境变量可以由子进程来继承,所以ls继承了PWD,所以ls知道了当前的路径,所以也就知道了mycmd的位制。
自主实现pwd环境变量:
非常简单,因为我们有了PWD环境变量,我们直接调用getenv就能实现PWD
我们也可以把mycmd的路径添加到环境变量PATH中。这样不需要./就可以调用我们自己实现的PWD。
问题:环境变量是怎么被子进程继承的(思考题目)
命令行参数:
main函数的参数列表叫做命令行参数。
我们思考一个问题:main函数的参数可以有几个。
main函数最多有三个参数,但是我们正常见的main函数一般只有两个参数。
我们对这两个参数进行解释:
参数argc是一个整型,argv是一个指针数组 ,argv指向的数组的元素个数是argc个。
这两个参数是谁传给main函数的?
答:我们可以理解为父进程或者系统传递给main函数。
我们对mycmd进行文本编辑:
当在命令行中输入的内容不断增多时,数组的内容也会自动变多。
我们可以这样理解:
例如我们在Linux中可以这样调用指令:
所以ls是一个程序,本质上也就是main函数,main函数的第一个参数我们不需要输入,随着第二个参数输入,第一个参数自动匹配,这里的-a -l -d表示我们向argv[]指针数组中传递的内容。
命令行参数的本质是依次把程序名和选项传递给数组argv
一共有几个选项,我们的argc就是多少,我们的argv数组的元素个数就是多少。
我们画图加强理解:
例如我们调用这样一个指令:
然后把这些字符传递给argv数组,ls传向第一个元素位置,a传到第二个元素位置等等。
这个数组的最后元素位置存放的是空指针。
从把我们写的指令进行解析,到把每一个字符放到argv数组中,都是由我们的命令行解释器,也就是shell完成的。
但是传这些选项的意义又是什么呢?
我们对mycmd.c进行编辑:
我们进行调用:
所以我们可以通过命令行中的选项来决定我们要调用什么的功能。
这和我们的这些指令是等价的:
main函数的第三个参数:
env是一个环境变量参数,是一个指针数组。
数组env存储的是指向环境变量的指针。
环境变量数组的末尾也是空指针。
所以环境变量就能被我们的进程拿到了,我们就可以使用环境变量了。
接下来,我们对观点进行证明:
如果我们的观点正确的话,我们应该可以打印出许多环境变量。
main函数最多三个参数
第一个参数argc是第二个参数数组argv的元素的个数,第二个参数是指针数组argv,我们可以通过输入指令(字符串)来决定我们调用什么程序的什么选项,这些程序和选项就被存放到数组argv中,第三个参数是指针数组env,数组中存放的是环境变量,我们通过该数组可以访问环境变量。
所以我们通过指令+选项+环境变量最终调用成功了一个进程。
所以解决上述一个问题:shell是怎么把环境变量传递给子进程的。
通过命令行参数,我们在shell中输入指令本质上就是调用main函数,我们把shell的环境变量以数组指针的形式传递给子进程,子进程就能够继承到环境变量了。
正常情况下,假如我们的main函数并没有传递环境变量数组,我们怎么拿到环境变量。
我们可以通过getenv的形式得到环境变量。
这里表示打印系统指令所在路径:
environ
environ是一个二级指针,指向的是环境变量表:
我们使用environ进行尝试:
environ[i]表示*(environ+i),表示指向环境变量的指针,我们根据该指针就能打印出对应的环境变量。
显示了所有的环境变量。
获取环境变量的三种方式:
最重要的是第一个getenv
putenv
表示更改或添加一个环境变量的值
stat
表示查看一个文件的所有属性:
例如:
我们提出一个问题:
这是我们当前的目录,假如我们重新登录我们的用户:
为什么pwd发生了变化。
因为我们的shell命令在我们重新登入用户时,检测我们的用户是bbb,用户的家目录是/home/bbb,然后我们通过某些cd命令就到了该路径下。
现象:
这两个到的路径是相同的,原因是cd ~检测到我们要到的路径是家目录,我们直接找到HOME环境变量,跳到HOME所在的路径处。
现象:
我们在main函数进行传参时,传递的env[]数组实际上传递的是environ,为什么呢?因为函数传参要发生降维,例如我们要把整型a传递给main函数,我们要传递a的地址,否则我们只能完成值拷贝,env是指针数组,发生降维,降维之后的结果就是二级指针,也就是environ。
echo的问题:
echo是一个进程,是shell的子进程,echo可以继承环境变量,但是无法继承本地变量,为什么这里还能显示本地变量val的值。
程序地址空间
我们之前讲的c++地址空间,这些空间的实质是什么?是内存吗?
不是内存,我们用现象进行解释:
把全局的mycmd替换成为mytest
我们首先理解一个理念:
只要是一个进程,就要被操作系统管理,只要被操作系统管理,在创建子进程时,就要拷贝父进程的内核数据结构,例如父进程有pcb,在创建子进程时拷贝父进程的pcb。
我们对mytest.c进行文本编辑:
我们创建一个变量global_value,接下来,我们创建子进程,当id<0表示fork失败,当id为0时,表示进行的是子进程,当id不为0时,表示进行的是父进程,我们在子进程运行到一定时间时修改global_value的值。
当我们修改了global_value的值,该变量的地址没有修改,两个地址相同的变量值却不同证明了这里的地址并不是真实的内存。
换言之:我们c语言学到的所有的地址,空间等等都不是真实的内存。
所以这里的地址以及我们c语言学的地址都是虚拟地址(线性地址)
感性理解虚拟地址空间
有一个大富翁,他有十亿美金,他有三个私生子,这些私生子都不知道彼此的存在,大富翁为了鼓励这些私生子努力工作,分别与三个孩子单独会面并且许诺他们在自己死后把全部的资产继承给这个孩子,所以所有的私生子都非常努力的工作,而且所有的私生子都认为十亿美金迟早是自己的。
但是私生子也需要花钱,于是每一个私生子就问大富翁要钱,每次只要1w美金。
所以,这十个亿的美金只是大富翁给所有私生子画的一个大饼。
我们以系统的方式进行理解:
大富翁就是操作系统,十亿美金就是内存,这三个私生子就是进程,所有的进程都认为自己会独占系统资源(实际上,这只是操作系统给进程画的饼)。
所有私生子要的1w美金只是进程申请的资源和空间。
给每一个儿子画的大饼就是进程地址空间。
操作系统如何画饼呢?
首先,画饼的本质是老板给员工的脑海了构建一个蓝图,如图所示:
假如有500个员工,老板和员工a许诺你以后要当部门总监,之后又对员工a许诺你以后要当总经理,这不就是乱套了吗?
所以不仅员工要被管理,老板画的饼也要被管理,老板画的饼叫做地址空间。
如何管理呢?
先描述,再组织。
所有的进程都以结构体的形式先描述,然后再以某种数据结构的形式再进行组织。
相关文章:

环境变量和进程地址空间
目录 环境变量: env:显示所有的环境变量: echo $环境变量名表示查看环境变量的值 理解环境变量: getenv:显示环境变量的值 export set命令:显示所有变量 unset取消变量: pwd:当…...

【数据结构】栈和队列
目录 一、栈 1、栈的定义 2、栈的模拟实现(顺序栈) 1、创建一个顺序结构的栈 2、实现压栈方法(push) 3、模拟实现pop方法(出栈) 4、模拟实现peek(查看) 5、测试上述方法 3、栈的应用场景 1、改变元…...

sql复习(视图、Top-N分析、其他数据库对象)
一、视图view 1.视图定义 视图是一种虚表。 视图建立在已有表的基础上, 视图赖以建立的这些表称为基表。 向视图提供数据内容的语句为 SELECT 语句, 可以将视图理解为存储起来的 SELECT 语句。 视图向用户提供基表数据的另一种表现形式。 2.使用视图的好处 控制数据访问 简…...

2023年私募股权基金研究报告
第一章 概况 PE是私募,也即私募投资基金,是指以非公开发行方式向合格投资者募集的,投资于股票、股权、债券、期货、期权、基金份额及投资合同约定的其他投资标的(如艺术品、红酒等)的投资基金,简称私募基金…...
Redis单点故障+红锁原理
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、Redis单点故障二、红锁原理三、Redission实现了红锁一、Redis单点故障 单台redis容易出单点故障采用集群,获取到锁之后数据持久化到rdb,aof文件中从节点有可能在从主节点拿到数据之前,主节点…...
数据库中的存储过程
1、创建存储过程create procedure sp_name[参数名] [类型],[参数名] [类型]asbegin.........end以上格式还可以简写成:create proc sp_name[参数名] [类型],[参数名] [类型]asbegin.........end/*注:“sp_name”为需要创建的存储过程的名字,该…...

基于 VPX 总线的工件台运动控制系统研究与开发-DSP+FPGA硬件架构(一)
作为光刻机核心单元之一,超精密工件台主要负责实现快速扫描、上下片、精密定位、调平调焦等功能。目前,较为成熟的方案大多采用 VME 并行总线架构来建立超精密工件台控制系统,由于随着系统性能要求的提升,VME 总线以及相应的处理器…...
Android 9.0 根据包名授予app所需的权限
1.概述 在9.0的系统rom产品定制化开发中,在对系统app首次启动默认是会弹出授权的弹窗的,但是对于产品来说会显示的有些麻烦,对产品体验度也不是很好,所以在进行产品开发的时候,默认要求对一些app根据包名授予权限,这样就不会弹出授权的窗口了默认就有权限了,接下来就来实…...
如何将Python包发布到PyPI上,使用pip安装自己的库
如何发布自己的第三方库1. PyPi的用途2.Python包发布步骤2.1 创建目录结构2.2 准备文件1、README.rst2、LICENSE.txt,创建许可证3、setup.py文件4.克隆setup.py仓库(推荐)2.3 编写核心代码2.4 生成分发档案2.5 发布包到PyPi3.验证发布PYPI成功…...

【Git】git常用命令总结
简言 git是一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理。 里面有很多常用的命令语法,在此做一个常用命令总结记录,以备不时之需。 命令总结 由于git是基于linux开发的工具,所以有个特点&a…...

Cortex-M0中断控制和系统控制
目录1.NVIC和系统控制块特性2.中断使能和清除使能3.中断挂起和清除挂起4.中断优先级5.中断控制的通用汇编代码使能和禁止中断设置和清除中断挂起状态设置中断优先级6.异常屏蔽寄存器(PRIMASK)7.中断输入和挂起行为8.中断等待9.系统异常的控制寄存器10.系…...

科技云报道:2023,云计算的风向变了
科技云报道原创。 2022,是云计算的“分水岭”之年。 与前两年的火热相比,2022年云计算行业实属不太好过:阿里云一季度营收增速创出历史新低,腾讯云的市场份额也被后来者华为云反超,沦为第三。 在此情形下,…...
工程管理系统源码-专注项目数字化管理-工程管理
工程项目各模块及其功能点清单 一、系统管理 1、数据字典:实现对数据字典标签的增删改查操作 2、编码管理:实现对系统编码的增删改查操作 3、用户管理:管理和查看用户角色 4、菜单管理:实现对系统菜单的增删改查操…...

Nacos详细使用操作文档(图文详细)
文章目录Nacos详细使用操作文档(图文详细)1、安装2、Nacos作为注册中心2.1、Nacos服务注册【ICRMS】2.2、Nacos 服务调用2.2.1、Feign 远程调用【Personnel】2.2.2)、RestTemplateRibbon 远程调用【Personnel】3、Nacos作为配置中心4、Nacos 命令空间5、Nacos配置文件参数详解N…...
如何评价2023年美赛ABC题目
A题 遭受干旱侵袭的植物群落 背景 不同种类的植物对压力的反应方式不同。例如,草原对干旱非常敏感。干旱发生的频率和严重 程度各不相同。大量的观察表明,不同物种的数量在植物群落如何适应连续几代的干旱周期中 起着重要作用。在一些只有一种植物的…...

Win10显示dds及tga缩略图
整理之前做游戏MOD时收集的模型资源,3D游戏模型的贴图文件格式基本都是dds或tga的,毕竟无损压缩、支持嵌入MipMap、带透明通道、可以被GPU硬解balabala...道理我都懂但这俩玩意系统根本直接查看不了,就算装上专门的看图软件或插件,文件夹视图下也没有缩略图预览,只能一个个点开…...

Lesson5.1---Python 之 NumPy 简介和创建数组
一、NumPy 简介 NumPy(Numerical Python)是 Python 的一种开源的数值计算扩展。这种工具可用来存储和处理大型矩阵,比 Python 自身的嵌套列表(nested list structure)结构要高效的多(该结构也可以用来表示…...

Exchange 2013升级以及域名绑定等若干问题
环境简介Exchange 2013服务器位于ad域中,系统为Windows server 2012 R2,其内部域名为:mail.ad.com一. Exchange客户端无法在浏览器中正常运行在域中部署Exchange服务器后,除了可以通过outlook、foxmail等邮件客户端来使用邮箱功能…...

linux安装jenkins
1. 官网寻找安装方式 进入到jenkins官网,找到对应的下载页面:https://www.jenkins.io/download/ 根据自己系统还有想要使用的版本,进行选择即可。这里我们使用CentOS作为示例,版本选择长期支持版(LTS) 2.…...

【MySQL】MySQL表的增删改查(CRUD)
✨个人主页:bit me👇 ✨当前专栏:MySQL数据库👇 ✨算法专栏:算法基础👇 ✨每日一语:生命久如暗室,不碍朝歌暮诗 目 录🔓一. CRUD🔒二. 新增(Creat…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...

windows系统MySQL安装文档
概览:本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容,为学习者提供全面的操作指导。关键要点包括: 解压 :下载完成后解压压缩包,得到MySQL 8.…...
DAY 26 函数专题1
函数定义与参数知识点回顾:1. 函数的定义2. 变量作用域:局部变量和全局变量3. 函数的参数类型:位置参数、默认参数、不定参数4. 传递参数的手段:关键词参数5 题目1:计算圆的面积 任务: 编写一…...