【linux进程(六)】环境变量再理解程序地址空间初认识
💓博主CSDN主页:杭电码农-NEO💓
⏩专栏分类:Linux从入门到精通⏪
🚚代码仓库:NEO的学习日记🚚
🌹关注我🫵带你学更多操作系统知识
🔝🔝

程序地址空间
- 1. 前言
- 2. 在bash中查看所有环境变量
- 3. 程序中获取环境变量的方式
- 4. main函数的第三个参数解析
- 5. 本地的与env中的环境变量
- 6. 配置文件与环境变量的全局性
- 7. 内建命令与常规命令
- 8. 程序地址空间初认识
- 9. 深入探究地址空间与物理内存
- 10. 总结
1. 前言
如果你不知道什么是环境变量PATH
请先阅读下面的文章:
初识环境变量
本章重点:
本篇文章着重于完善上一篇文章遗留
的一些环境变量的问题,认识其他几个
常见的环境变量,以及在bash下查看
环境变量和添加环境变量的方式,以及
拓展main函数的第三个参数:env.
最后对程序地址空间的内容开个头!
2. 在bash中查看所有环境变量
在bash中查看所有环境变量:
使用指令:
env

可以看见打印出密密麻麻的环境变量
这其中不需要我们全部记住,只需简单
的认识几个常见的环境变量即可!
环境变量PWD:

记录当前路径,你以为平时执行的
pwd指令是怎么知道当前路径的?
稍加思考就能窥探,pwd实际上调用
了PWD环境变量!
环境变量HOME

我们平时使用的指令:cd ~进入
家目录,哪儿是家目录?环境变量
HOME里面的内容就是家目录!
简述登录Xshell时,所要做的事
根据以上对环境变量的认识,我们发现
登录xshell时我们用root账户登录就
会跑到root的家目录下,这是因为在
启动Linux时,OS帮我们做了一些事情
-
输入用户名,密码
-
认证信息是否正确
-
形成环境变量(PATH,PWD,等等)
-
根据用户名初始化HOME环境变量
HOME=root或HOME=XXX -
cd $HOME(进入家目录)
3. 程序中获取环境变量的方式
我们知道,Linux是由C语言写的
所以这里的程序我们默认是C程序
使用函数:
getenv()

使用方法如下:
char* p = NULL;
p = getenv("PATH");
p就能获取环境变量PATH的内容了
即函数的参数是环境变量的名字
返回值是环境变量的内容!
4. main函数的第三个参数解析
不卖关子,直接写出来:
int main(int argc,char* argv[],char* env[])
第三个参数为env,是不是很熟悉?
没错,第三个参数就是环境变量
它和第二个参数一样是指针数组
它指向环境变量表,环境变量表中的
内容和在bash中使用env打印的一样!
到目前为止了解到,系统在启动
程序时会给main函数提供两张表:
命令行参数表环境变量表
通过下面的代码查看环境变量表:
#include<stdio.h>
int main(int argc,char* argv[],char* env[])
{for(int i=0;env[i]!=NULL;i++){printf("[%d]: %s"\n,i,env[i]);}return 0;
}
5. 本地的与env中的环境变量
我们可以在bash中直接定义环境变量
使用指令:
环境变量名=内容
比如:

用户自己定义的环境变量是本地的
而env并不能查看本地的环境变量
所以使用env查找刚才定义的环境变量
时,实际上会找不到!

如果想要我们定义的环境变量
被放在系统的环境变量表中应该怎么做?
使用指令:
export 环境变量名

还可以使用export定义环境变量:

6. 配置文件与环境变量的全局性
根据上面的一些信息我们可以推论:
在修改/定义环境变量时,实际上
修改/定义的是bash进程内部的
环境变量信息,每一次重新登录都会
形成新的bash解释器,并且新形成
的bash解释器会自动从家目录下
的bash_profile文件中读取信息形成
一份新的环境变量表!
所以为啥每次重新启动bash后
我们自己定义/修改的环境变量
就不见了?因为它并没有被保存在
配置文件bash_profile中!
查看配置文件bash_profile:

当我们在配置文件中加上自己想要
一直存在的环境变量时,此时bash再
次启动后,这个环境变量就会被放到
环境变量表中!
并且在创建子进程时
这张表会通过main函数的参数传递
给子进程,所以子进程有了和父进程
一样的环境变量表,而子进程创建孙子
进程时又会将子进程的表给孙子进程
所以说,环境变量具有全局性!
本地变量 VS 环境变量
1. 本地变量只在bash进程内部有效,不会被子进程继承
2. 环境变量通过让所有子进程继承的方式,实现自身的全局性
7. 内建命令与常规命令
我们知道一个事实,bash中的指令
可以直接使用,不用加./是因为它的
路径在环境变量PATH中,所以我们
将PATH置空后,这些命令就不能运行了!

我们会发现一个问题,PATH被置空后
确实有些命令是跑不了了.但是某些
命令还是能跑,比如pwd命令还能正常
输出,这是为啥呢?
Linux下的命令父分类:
常规命令:bash创建子进程执行的内建命令:bash自己执行的(类似于一个函数)
很明显pwd是内建命令,echo也是
内建命令,难道你就没有一个疑惑吗?
为什么我们自己定义的环境变量在
环境变量表env中找不到,但是echo
命令却可以将它的内容打印出来?
echo程序也是bash的一个进程
为什么它能获取我们定义的环境变量?
答案是echo是内建命令,是父进程
自己内部执行的,所以它可以看见
父进程的变化,但是其他的子进程不能
接受父进程的本地变量,所以看不见!
8. 程序地址空间初认识
C/C++程序员认为,程序的内存分布是这样的:

堆是向上增长的,栈是向下增长的
这个我们在以前的学习中以及有所
了解了,那为什么这里还要提呢?
有两个目的:
再对以前的知识做复习在原有知识的基础上拓展
这其中有两个地方需要注意:
在写C程序时定义的常量字符串
实际上在上面区域的正文代码区
因为它和正文代码区紧挨着,所以
常量区的字符串不允许修改!
第二点是,栈虽然说是向下增长的
但是栈中的数组,结构体等结构的
地址是向上增长的,比如说开辟数组
时,开辟十个空间,那么数组中第一个
元素在空间的最下面,也就是地址最低
处,然后依次往上放后面的元素
9. 深入探究地址空间与物理内存
现在写上这样一段代码来深入探究地址:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include<stdlib.h>
int main()
{ int id=fork(); int tmp=10; if(id==0)//子进程执行的代码 { tmp=20; while(1) { printf("子进程,tmp: %d,&tmp: %p\n",tmp,&tmp); sleep(1); } } if(id>1)//父进程执行的代码 { while(1) { printf("父进程,tmp: %d,&tmp: %p\n",tmp,&tmp); sleep(1); } } return 0;
}

我们发现,tmp的值在父子进程中
是不同的,可以我们暂时可以理解,
是因为写时拷贝, 但是相同的地址
为什么会有不同的值? 这就有一点
挑战我们之前学习的知识了!
以目前的知识储备是无法想明白这个问题的
但是我们可以得出一个小结论:
我们平时写的堆区,栈区,静态区
等等区,并不是真实的物理地址!
因为一个物理地址不可能有两个值
那么真实的物理地址到底是什么?
如果这个不是真实的物理地址那么
这个地址又是什么东西呢?我们打印
出来的地址又是什么东西?以上内容
将在下一篇文章讲解!
10. 总结
了解环境变量相关知识可以更好的
理解操作系统在启动时所做的工作,
以及可以更好的了解进程在运行的
时候需要的一些数据从何而来!
本篇文章不再做拓展,更多内容
将在下一篇文章中讲解
相关文章:
【linux进程(六)】环境变量再理解程序地址空间初认识
💓博主CSDN主页:杭电码农-NEO💓 ⏩专栏分类:Linux从入门到精通⏪ 🚚代码仓库:NEO的学习日记🚚 🌹关注我🫵带你学更多操作系统知识 🔝🔝 程序地址空间 1. 前言2. 在ba…...
10步开启SAFe敏捷发布列车
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 敏捷畅想一、培训 SAFe 项目顾问 (SPC)二、培训精益敏捷领导者三、 举办价值流研讨会并确定您的第一个敏捷发布系列四、 定义/设置 ART 和团队五、 担任重要角色六、…...
面试题之Vue和React的区别是什么?
一提到前端框架,相信大家都对Vue和React不陌生,这两个前端框架都是比较主流的,用户也都比较多,但是我们在使用这些框架的时候,是否对这两个框架之间的区别有所了解呢?接下来,让我们来一起的系统…...
Linux基础知识——概述和常用文件管理命令
Linux基础知识——概述和常用文件管理命令 文章目录 Linux基础知识——概述和常用文件管理命令概述常用的一些文件指令 概述 终端:一个terminal窗口就是以个屏幕, 远程连接了一个服务器, 每一个terminal可以连接到任何一个其他服务器上;关掉terminal相当于只是关掉…...
腾讯云创建了jenkins容器,但无法访问
1、首先,查看本机能不能ping通你的腾讯云服务器 如果ping的通那就下一步 2、查看腾讯云服务器的防火墙关了没,没关关掉、 firewall-cmd --state not running 3、那就在云服务器的控制台开放端口...
C语言的const函数修饰指针
文章目录 一、const函数的作用 int a 10; int *p ; p &a;从上面的代码分析,p 存放的就是a的地址, *p 存放的就是 a 的值。 一、const函数的作用 一旦使用了const函数修饰一个变量,那么这个变量就无法变化了。 所以下面三种情况&#…...
EasyExcel使用方式(包含导出图片)
1、导EasyExcel依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.3.2</version> </dependency> 2、创建导出excel的实体类 Getter Setter EqualsAndHashCode HeadStyle(fillF…...
redis学习(三)——java整合redis
Jedis Jedis可以用于java连接redis数据库 新建一个maven项目,导入Jedis依赖 <dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>RELEASE</version><scope>test…...
OpenText 安全取证软件——降低成本和风险的同时,简化电子取证流程
OpenText 安全取证软件,行业标准的数字调查解决方案,适用于各种规模和各种行业的组织 降低成本和复杂性 • 远程调查比轮流调查过程更有效 对结果持有信心 • 磁盘级可见性可以完成相关端点数据的搜索和收集 谨慎调查 • 完整的网络调查…...
【vue】vue前端、生产(线上)环境请求unicloud云服务空间axios报错
目录 原因总结:借助Nginx使得axios可跨域请求 原因 使用axios的时候,如果是开发环境下,WebStorm(IDEA)会自带跨域功能,说白了就是不用考虑跨域的事情了。但是在生产环境下,vue前端编译成静态文…...
JVM详解(InsCode AI 创作助手)
JVM是一个虚拟的计算机,它有自己的硬件架构,如处理器、堆栈和寄存器等,也有自己的指令系统。JVM的主要任务是负责加载、验证、编译和执行Java程序。 一、JVM参数默认配置如下 内存设置: 初始堆内存大小:物理内存的1/…...
华为c语言编程规范
提示:附件为编程规范 文章目录 前言一、华为c语言编程规范总结 前言 例如:华为规范下载 一、华为c语言编程规范 该处使用的url网络请求的数据。 总结 提示:这里对文章进行总结: 例如:以上就是今天要讲的内容…...
SQL Server Management Studio (SSMS)的安装教程
文章目录 SQL Server Management Studio (SSMS)的安装教程从Microsoft官网下载SQL Server Management Studio安装程序。选中安装程序右键并选择“以管理员的身份运行”选项选择安装目录,单击“安装”按钮开始安装过程安装成功界面安装完成后,您可以启动S…...
React 图片瀑布流
思路: 根据浏览器宽度,确定列数,请求的图片列表数据是列数的10倍,按列数取数据渲染 Index.js: import React from react import { connect } from react-redux import { withRouter } from react-router-dom import { SinglePag…...
C++数据结构X篇_21_插入排序(稳定的排序)
文章目录 1. 插入排序原理2. 算法图解3. 核心代码:4. 插入排序整体代码实现 1. 插入排序原理 插入排序是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相…...
【Unity】3D跑酷游戏
展示 finish_all * 方块跑酷 1.教程链接 翻墙:https://www.youtube.com/watch?v9ZEu_I-ido4&listPLPV2KyIb3jR53Jce9hP7G5xC4O9AgnOuL&index3 2.基础制作 最终成果 2.1 基本场景 1.创建Cube作为跑道 1)记得把位置Reset; 2&#…...
bp前端验证码绕过及token绕过
前端验证码绕过及token绕过 原文参考:xiu 文章目录 前端验证码绕过及token绕过原文参考:[xiu](http://www.xiusafe.com/2023/10/25/%E9%AA%8C%E8%AF%81%E7%A0%81%E7%BB%95%E8%BF%87/)1 验证码爆破1. 登录Pikachu,先获取登录的api接口2 验证码…...
Jmeter(十四):跨线程组传递jmeter变量及cookie的处理详解
setUp线程组 setUp thread group 一种特殊类型的线程组,用于在执行常规线程组之前执行一些必要的操作。 在 setup线程组下提到的线程行为与普通线程组完全相同。不同的是执行顺序--- 它会在普通线程组执行之前被触发; 应用场景举例: A、测…...
css实现圆形进度条
能用现成组件就用,实现不行再自己写,因为牵扯到上传文件,进度实时出不来,所以只能使用dom元素操作; 1.实现 效果: 上图是100%,如果需要根据百分比显示,我们需要看下代码里面left和…...
适用于 Windows 10 和 Windows 11 设备的笔记本电脑管理软件
便携式计算机管理软件使 IT 管理员能够简化企业中使用的便携式计算机的部署和管理,当今大多数员工使用Windows 笔记本电脑作为他们的主要工作机器,他们确实已成为几乎每个组织不可或缺的一部分。由于与台式机相比,笔记本电脑足够便携…...
VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...
springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...
