环境变量小节

这是写的第二篇环境变量博客,写了一年多了,第一次出现把自己博客删了的情况,不知道为什么明明发表了,然后就把草稿箱和回收站的删了,结果晚上发现没发表,回收站删除是无法找回的,以后还是要慎重点。

一 常见环境变量

1 PATH

为什么我们在执行自己的可执行程序时往往要带上路径呢? 为什么执行ls指令就不用带路径呢?其实就是环境变量PATH的原因,我们打印看看PATH里面发现有很多路径。

**其中有个路径是/usr/bin恰好就是ls可执行文件所在的位置,**实际上就是ls这些指令会默认去PATH中的路径查找文件,而我们的文件的路径不在其中,所以必须告诉bash路径,才能去执行。

那如何添加呢,如下:但如果是PATH=/home/hqy,则会覆盖里面的路径。

如下,我们自己的test2这个可执行程序就可以不带路径了,但是有点奇怪的是有一个test文件却还是要带路径执行。

2 HOME

每次我们登录上shell的时候,我们就默认到了某个目录下,这个目录其实称为家目录,而这个家目录就是HOME维护的,每次登录时bash自动cd到这个目录下。

3 其余环境变量

env就可以显示所有的环境变量。

HISTSIZE=3000,指的是会保留历史上使用过的指令,最多三千条,这个挺好用的,用<-和->就可以找指令,有时候还挺方便的。USER=hqy这个保存的是当前用户名,还有那个一大团的是ls的配色方案,所以ls显示出的目录,可执行程序会带颜色。

4 和环境变量相关的指令

export 加上变量名会增加一个环境变量,unset则会删除,至于env则是显示全部的环境变量。

二 环境变量和进程

环境变量并不是凭空冒出来的,它其实已经存在我们身边很久了,这就得先说说main函数的参数了 。main函数其实是有参数的,诶那为什么我没写过形参,不报错呢?简单理解就是main函数其实是被进程起的CRT_Start()等函数调用的,或许进程在用CRT_start()函数调用main函数时,提前看了看你有没有写参数,没写,那我就不传,写了,我就传参。

那main函数的参数究竟是什么呢?我们运行一下test这个程序。

先前已经在初识父子进程中提过,./test其实是bash起了个子进程去执行代码,bash会先对我们输入的指令做解析**,按空格分割成一个一个的字符串,然后存到一个指针数组中,最后传给main函数的argv参数,而argc则是分割后的字符串个数。**

诶,我好好./test运行我的可执行程序不行吗,我好端端输入-a -l -b干嘛,回忆下ls命令,ls可以执行,ls -a -l也可以执行,但是ls -a -l和ls执行的是不同的代码,我们将"ls" "-a" "-l" 称为命令行参数,而-a -l则是选项,这个参数就是为了在ls代码块判断,然后执行不同的代码,显示不同的信息,如下图:

这就是选项的意义,而argv数组就是用来支持选项的。到了后面实现shell的时候,我们就能理解指令带ls的用处,以及带-a -l的作用。

而环境变量就和第三个参数env有关,它内部又是什么呢?我们打印看看。

**原来是环境变量,可是我本来就能用getenv获取环境变量啊,再传个这个参数给我干什么呢?**其实这个是为了后面我们可能想要用自己的环境变量表,就设置了这么一个参数,用来接收,怎么传要到程序替换再提及。

三 其余概念补充

1 全局属性

bash的环境变量具有全局属性:嘶,这句话如何理解呢?我们之前说./test这样运行的可执行程序是bash的子进程,这个子进程共享父进程的代码和数据,环境变量实质上也是数据,所以子进程也能用,这就是为什么子进程getenv可以看到bash的环境变量的原因。测试如下,我们给bash导入一个环境变量,然后看看子进程有没有继承到。

导入成功了,./test运行下,看看有没有。

有,说明猜想正确。**而所有我们在shell运行的程序都是bash的子进程或者子进程的子进程,这样不断地父传子,最后所有的进程如果不修改,那就都能看到bash的环境变量,**这就是全局属性。

2 本地变量和环境变量

**还有种变量称为本地变量,本地变量并不会被子进程所继承,只能给当前进程使用。**MAX=11111111111111这个就是定义一个本地变量,我们env一下就会发现,环境变量表中没有这个MAX变量,子进程也看不到。

3 内建命令介绍

有些指令其实是不适合让bash去起子进程执行的,简单理解内建命令就是bash内的一个函数,没有fork子进程去执行代码。

1 cd命令

cd命令是改变进程的工作目录cwd ,而环境变量PWD 是改变后顺便更新的,**如果这个时候起了子进程去chdir,这个时候就变成改变子目录的cwd了,****测试cd 是改变cwd得会用程序替换才可以复现实验,具体就是我分别用chdir和getenv("PWD")分别改变工作目录和环境变量,再用ls指令替换后面的代码,**我们会发现,ls显示的目录的信息是随着chdir改变的,而与是否改变环境变量无关。

2 echo命令

**为什么说echo命令也是呢,就是因为shell的echo可以打印本地变量,**如果bash创建了子进程去执行,是无法打印bash的本地变量的,不过我们在系统路径下却可以找到一个echo的可执行程序,不是说是个函数吗,怎么还有个可执行文件呢?个人感觉echo在打印时会做判断,在打印本地变量时不会创建子进程,但是有时候却会创建子进程,例如重定向的时候。

3 export命令

MAX=11111111111111这样只是定义一个本地变量 ,要想定义一个环境变量,得用export变量,而且export肯定是给bash导入的,**如果创建子进程导入环境变量,会发生写时拷贝,这样就不是给bash导入的了,诶,我就不想给bash导,**如果export是给子进程导,那有一天我想给bash导入呢,难道给bash创建个父进程吗。

后面在进程部分,环境变量也起到不小的作用,后续使用再介绍。

相关推荐
盛世宏博智慧档案1 分钟前
数据追溯 + 异常预警:机柜温湿度以太网变送器应用实践方案
linux·服务器·网络
leandzgc1 分钟前
Linux动态存储管理的逻辑卷使用示例
linux·运维·服务器·逻辑卷·linux动态存储管理
Lethehong5 分钟前
openEuler的系统监控:高效运维管理
运维
Jurio.32 分钟前
Python Ray 分布式计算应用
linux·开发语言·python·深度学习·机器学习
潮流coder1 小时前
ssh公钥 key生成
运维·ssh
守城小轩1 小时前
基于Chrome140的Reddit账号自动化(关键词浏览)——运行脚本(三)
运维·自动化
eventer1231 小时前
构建 HertzBeat Docker 镜像的技术实践
运维·docker·容器
深耕AI1 小时前
【wordpress系列教程】02 Blocksy主题
运维·服务器·前端
遇见火星2 小时前
Jenkins核心部署流程
运维·jenkins