Linux 环境变量 二
目录
获取环境变量的后两种方法
环境变量具有全局属性
内建命令
和环境变量相关的命令
c语言访问地址
重新理解地址
地址空间
获取环境变量的后两种方法
main函数的第三个参数 :char* env[ ]
也是一个指针数组,我们可以把它的内容打印出来看看。
#include<stdio.h> #include<stdlib.h> #include<string.h> E>int main(int argc,char* argv,char* env[]) { int i=0; for(; env[i];i++) {
E> printf("env[%d]:%s\n",i,env[i]); } return 0;
}
我们再把pid也打印出来看看:
输入命令:
!man getpid
我们把这两个头文件加上
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<sys/types.h>
E>#include<unistd.h>
E>int main(int argc,char* argv,char* env[]) { int i=0; for(; env[i];i++) {
E> printf("pid:%d,env[%d]:%s\n",getpid(),i,env[i]); } return 0;
}
就可以把我们的此程序的环境变量打印出来:
这个获取环境变量的方法和我们输入"env"命令获取的环境变量是一样的:
我们之前说过如果我们把PATH置空,很多系统命令都用不了了:
但是我们重启xshell之后就又可以用了。这是因为我们置空的是加载进内存的PATH。
我们重启之后系统解释器会重新读取环境变量表,形成新的环境变量,环境变量是脚本配置文件的形式存在的的。
在家目录下有个隐藏文件,bash_profile.
环境变量表就在这个文件里面。
假设我们自己写一个环境变量,
然后用env调用环境变量,通过管道只打印我们自己写的环境变量,显示找不到:
这是因为我们写的环境变量并没有被加载进环境变量表。
我们可以通过 "export"命令把我们写的环境变量加载进环境变量表里面,再通过env打印就可以打印出来了。
但是我们重启xshell之后我们配置的这个环境变量仍然会消失不见。只有当我们去家目录下面的bash_profile文件下写入我们的环境变量才能再次重启之后仍然会存在。
vim ~/.bash_profile
此刻我们就可以把我们自定义的变量打印出来看看:
假如我们不想给main函数传参呢?
有个外部变量叫 environ
它指向了char * env[ ]
我们把environ打印出来,main函数不带参照样可以把环境变量打印出来。
int main()
{ extern char** environ; int i=0; for(;environ[i];i++) { printf("%d,%s",i,environ[i]); } return 0;
}
到目前为止,我们获取环境变量的方法有:
main函数传参 getenv[ ] char** environ[ ]
环境变量具有全局属性
我们在我们将才的进程里再写个子进程,看它能获取我们子进程的环境变量吗
#include<stdio.h> #include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<unistd.h> int main()
{ pid_t id=fork(); if(id==0) { extern char** environ; int i=0; for(;environ[i];i++) { printf("%d,%s",i,environ[i]); } } sleep(3); return 0;
}
照样可以,这也证明了环境变量具有全局属性。
我们自定一个本地变量
OUR_ENV=333
然后我们再把这个本地变量打印出来
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<sys/types.h> #include<unistd.h> int main() {
printf("OUR_ENV_ENV:%S\n",getenv("OUR_ENV"));return 0;
}
注意:因为是子进程,所以我们没export的时候子进程获取不到我们自定义的本地变量,会显示为null
当我们export把我们定义的环境变量载入bash之后,让它成为环境变量,环境变量具有全局性,子进程就可以获取到了:
内建命令
我们再写几个本地变量:
我们发现,a,b都为本地变量,echo是一个子进程,但是可以直接打印本地变量 a,b,这是为什么?
再比如,我们把PATH置空,这时候ls,touch这种命令都用不了了,但是echo还可以用
这是因为echo是shell的内置函数,这种命令叫做linux的内建命令。
内建命令不创建子进程。
和环境变量相关的命令
set:
把本地变量和环境变量全部打印出来:
set | grep+本地变量名功能:打印本地变量
c语言访问地址
程序的地址空间遵守的就是下面这张图:
我们把这各个区的存的值的地址打印出来看看:
int usa; int bbb=100; int main () { printf("公共代码区:%p\n",main); const char* str="helo djwd"; //常量区 printf("常量区:%p\n",str); printf("初始化全局数据区:%p\n",&bbb); W>printf("未初始化全局数据区:%p\n",usa); char* heap=(char*)malloc(100); printf("堆区:%p\n",heap); printf("栈区:%p\n",&str);
观察打印出来的地址可以发现一个问题,从公共代码区到常量区,再往下走,地址都是呈递增状态。
当到了堆区之后,从堆区到栈区,中间宽度变的特别大。
按照这个结果我们可以有这种推论:
得出结论:堆和栈相对而生。
验证
把堆区地址打印看一下:
char* heap1=(char*)malloc(100);
char* heap2=(char*)malloc(100);
char* heap3=(char*)malloc(100);
char* heap4=(char*)malloc(100); printf("堆区:%p\n",heap);
printf("堆区:%p\n",heap1);
printf("堆区:%p\n",heap2);
printf("堆区:%p\n",heap3);
printf("堆区:%p\n",heap4);
可以发现堆区越来越大,这也证明堆区向上增长
把栈区地址打印一下看一下:
char* str="hello";
char* heap1=(char*)malloc(100);
char* heap2=(char*)malloc(100);
char* heap3=(char*)malloc(100);
char* heap4=(char*)malloc(100); printf("栈区:%p\n",&str);
printf("栈区:%p\n",&heap);
printf("栈区:%p\n",&heap1);
printf("栈区:%p\n",&heap2);
printf("栈区:%p\n",&heap3);
printf("栈区:%p\n",&heap4);
观察图我们发现栈区越往下越小
如果定义一个结构体object ,里面有三个成员变量 int a,b,c,abc谁最大?
struct d
{ int a; int b; int c;
}object; printf("%p\n",&object.a);
printf("%p\n",&object.b);
printf("%p\n",&object.c);
很明显,c最大
这是因为虽然栈区向下增长,但整体是向上增长的:
假设我们定义一个 int b,一个int类型有4个字节,那就应该有4个地址,但是我们打印b的地址,显示出来只有一个,这个地址就是最小的地址。
然后向上按照int类型访问4个字节,访问到最大字节:
类型的本质叫做偏移量
c语言中就是以起始位置+偏移量访问任何地址。
定义一个int a,打印a的地址。
a因为是常量,所以在栈区,又因为后开辟,所有地址偏小。
现在我们a重定义为 static int a,此刻再重新打印a。我们发现a的地址变量,它和全局变量的地址是一个样子,也就是此时a就是一个全局变量:
所以我们可以说已初始化全局变量区就是静态区:
在栈区之上还有一个环境变量区和命令参数区:
重新理解地址
地址空间
写一个子进程,写一个父进程
pid_t id=fork();
相关文章:

Linux 环境变量 二
目录 获取环境变量的后两种方法 环境变量具有全局属性 内建命令 和环境变量相关的命令 c语言访问地址 重新理解地址 地址空间 获取环境变量的后两种方法 main函数的第三个参数 :char* env[ ] 也是一个指针数组,我们可以把它的内容打印出来看看。 …...

Beyond Compare4 30天试用到期的解决办法
相信很多小伙伴都有在使用Beyond Compare 4软件,如果我们没有激活该软件,就只有30天的评估使用期,那么过了这30天后我们怎么继续使用呢?下面小编就来为大家介绍方法。 打开Beyond Compare4,提示已经超出30天试用期限制…...

sentinel规则持久化-规则同步nacos-最标准配置
官方参考文档: 动态规则扩展 alibaba/Sentinel Wiki GitHub 需要修改的代码如下: 为了便于后续版本集成nacos,简单讲一下集成思路 1.更改pom 修改sentinel-datasource-nacos的范围 将 <dependency><groupId>com.alibaba.c…...

【Linux】tail命令使用
tail 命令可用于查看文件的内容,有一个常用的参数 -f 常用于查阅正在改变的日志文件。 语法 tail [参数] [文件] tail命令 -Linux手册页 著者 由保罗鲁宾、大卫麦肯齐、伊恩兰斯泰勒和吉姆梅耶林撰写。 命令选项及作用 执行令 tail --help 执行命令结果 参…...

【数据结构】面试OJ题——时间复杂度2
目录 一:移除元素 思路: 二:删除有序数组中的重复项 思路: 三:合并两个有序数组 思路1: 什么?你不知道qsort() 思路2: 一:移除元素 27. 移…...

LibreOffice编辑excel文档如何在单元格中输入手动换行符
用WPS编辑excel文档的时候,要在单元格中输入手动换行符,可以先按住Alt键,然后回车。 而用LibreOffice编辑excel文档,要在单元格中输入手动换行符,可以先按住Ctrl键,然后回车。例如:...

ideaSSM在线商务管理系统VS开发mysql数据库web结构java编程计算机网页源码maven项目
一、源码特点 SSM 在线商务管理系统是一套完善的信息管理系统,结合SSM框架和bootstrap完成本系统,对理解JSP java编程开发语言有帮助系统采用SSM框架(MVC模式开发),系统具有完整的源代码 和数据库,系统主…...

数据结构 | 顺序表专题
数据结构 | 顺序表专题 文章目录 数据结构 | 顺序表专题课前准备1. 目标2. 需要的储备知识3. 数据结构相关概念 开始顺序表1、顺序表的概念及结构2、顺序表分类3、动态顺序表的实现初始化顺序表打印顺序表内存容量的检查顺序表的尾插顺序表的尾删顺序表的头插顺序表的头删在顺序…...

C++可视化 有穷自动机NFA 有穷自动机DFA
一、项目介绍 根据正则表达式,可视化显示NFA,DFA;词法分析程序 二、项目展示...

vite vue3 ts 使用sass 设置样式变量 和重置默认样式
1.安装scss 样式支持依赖 yarn add -D sass 2.使用sass <div><!-- 测试使用sass --><h1>测试使用sass</h1> </div><style scope lang"scss"> div {h1 {color: red;} } </style> 效果: 3.通过npm下载并复制…...
MySQL安全基线检查
目录 安全基线检查基础知识MySQL 的安全基线检查MySQL 更严格的一些基线检查内容一、安全基线检查基础知识 1、安全基线的定义: 安全基线是一个信息系统的最小安全保证,即该信息系统最基本需要满足的安全要求。它是在安全付出成本与所能够承受的安全风险之间进行平衡的合理…...

Unity主程如何做好游戏项目管理
前言 很多小伙伴最近在面试或者考虑跳槽,可能工作了3~5年了想涨薪或想做技术总监或主程, 可自己还是个雏,没有做过项目技术管理,怎么办?今天我给大家梳理一下作为一个技术总监或主程你应该如何带好一个游戏项目,做好技术管理。接…...

103.linux5.15.198 编译 firefly-rk3399(2)
1. 平台: rk3399 firefly 2g16g 2. 内核:linux5.15.136 (从内核镜像网站下载) 3. 交叉编译工具 gcc version 7.5.0 (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04) 4. 宿主机:ubuntu18.04 5. 需要的素材和资料ÿ…...

如何从Android手机上轻松恢复误删除的短信 ?
当您使用 Android 手机时,您可能会误删除一些 Android 短信。如果这些消息对您很重要,您可能想要恢复它们。在这种情况下,您可以尝试使用U1tData安卓数据恢复(奇客软件) 来完成这项工作。这篇文章将向您展示更多信息。…...

毅速丨金属3D打印能替代传统制造吗?
金属3D打印技术已经逐渐被很多行业认可和应用,但是目前,金属3D打印多数被作为传统制造技术的一种补充,暂时还不能完全替代传统制造。 金属3D打印使用的是金属粉末进行选择性激光烧结,打印时在成型缸里铺上金属粉末,打印…...
21个新的ChatGPT应用
自从GPT有了图识别功能后变的更加强大,特别是ChatGPT的视觉技术,为我们提供了无数的可能性。本文将深入探讨这21种应用场景,帮助理解其在日常生活和工作中的实际价值。 生活助手:为日常生活增添色彩 健身计划定制:你…...
【通信原理】第二章|确知信号
前言 那么这里博主先安利一些干货满满的专栏了! 首先是博主的高质量博客的汇总,这个专栏里面的博客,都是博主最最用心写的一部分,干货满满,希望对大家有帮助。 高质量博客汇总 文章目录 前言 第二章 确知信号1. 确知…...

【JVM】类加载器
【JVM】类加载器 文章目录 【JVM】类加载器0. 类加载器概述1. 类加载器的分类1.1 启动类加载器1.2 Java中的默认类加载器1.2.1 扩展类加载器1.2.2 应用程序类加载器 2. 双亲委派机制2.1 类的双亲委派机制是什么?2.2 打破双亲委派机制2.2.1 自定义类加载器2.2.2 线程…...

利用Excel支持JUnit参数化测试
在JUnit里面,可以使用CsvFileSource读取csv文件进行参数化测试,可是CSV文件不支持格式,编辑颇为麻烦,尤其是多次编辑,因此自然想到是否可以使用Excel文件,可以有各种格式,支持各类数据。 最新开…...

第三章 SysML入门|系统建模语言SysML实用指南学习
仅供个人学习记录 UML与SysML的联系 可以稍微参考UML与SysML的联系 UML(统一建模语言)和SysML(系统建模语言)是两种与建模相关的语言,它们之间存在联系和区别。 SysML的图分类如下图所示。 SysML 图概述 这里只…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
区块链技术概述
区块链技术是一种去中心化、分布式账本技术,通过密码学、共识机制和智能合约等核心组件,实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点:数据存储在网络中的多个节点(计算机),而非…...
基于鸿蒙(HarmonyOS5)的打车小程序
1. 开发环境准备 安装DevEco Studio (鸿蒙官方IDE)配置HarmonyOS SDK申请开发者账号和必要的API密钥 2. 项目结构设计 ├── entry │ ├── src │ │ ├── main │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ ├── H…...

spring Security对RBAC及其ABAC的支持使用
RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型,它将权限分配给角色,再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...
土建施工员考试:建筑施工技术重点知识有哪些?
《管理实务》是土建施工员考试中侧重实操应用与管理能力的科目,核心考查施工组织、质量安全、进度成本等现场管理要点。以下是结合考试大纲与高频考点整理的重点内容,附学习方向和应试技巧: 一、施工组织与进度管理 核心目标: 规…...