一.基本概念
* 环境变量 (environment variables) 一般是指在操作系统中用来指定操作系统运行环境的一些参数 * 如:我们在编写 C/C++ 代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但 是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。 * 环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性
查看当前Linux系统的环境变量:
env
在Windows下的环境变量:
环境变量本质上也是一种变量,是一种键-值的对应关系,由变量命和变量值组成。
二.查看Linux下的环境变量
1.查看具体的环境变量
echo $NAME//NAME是环境变量名称
如:
常见的环境变量:
PATH
指定命令的搜索路径.
1.我们平时写的一些C/C++代码,编译成可执行程序后,通过 ./可执行文件名运行可执行文件,而 ./ 的本质就是告诉操作系统可执行文件在那个路径(在那个目录里)
2.但是系统自带的指令,本质也是C语言写的程序,为什么系统的指令不需要 ./ 来指定的路径呢?
3.就是因为环境变量PATH的存在,在执行命令行上的程序时,操作系统会默认会在PATH上寻找。如程序在PATH的路径里,就输入 可执文件名 ,否则就必须输入 ./可执行文件名
注:PATH里面的路径以 / 为分隔符分离
HOME
指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
当我们每次登录系统的时候,系统就会记录下登录用户名,并且填充HOME环境变量,并且创建bash进程帮我们执行cd/home/xxx的命令,进入我们自己的家目录,这也是我们为什么刚进入就默认在家目录的原因。
普通用户的HOME
一般格式为 /home/用户名
root用弧的HOME
一般格式为:/root
4.SHELL
当前Shell,它的值通常是/bin/bash。
三.环境变量的组织方式
每个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串,数组的最后一个总是NULL。
四.添加环境变量
用export导入环境变量
在创建一个本地变量并赋值,再用指令:
export 环境变量名
但是我们会发现一个问题,当我们把程序关闭启动后,再次查看环境变量时,会发现SD这个我们曾经导入的环境变量消失了,那么我们要如何才能导入一个关闭启动后,仍然存在的环境变量呢?
这里我们就不得不提,在我们登录时,我们的bash进程的环境变量表是如何来的,
在我们每次启动时,bash进程都会读取.bash_profile配置文件中的内容,为我们bash进程形成一个一张环境变量表信息。因此要想导入一个程序关闭启动后,仍然存在的环境变量,我们就需要在.bash_profile文件里导入。
我们只需要在第8行之后添加我们在命令行导入环境变量的内容就行了。
五.环境变量的继承
1.环境变量是可以被子进程继承的。
2.子进程可以继承继承父进程的环境变量
3.但仅仅只是环境变量被子进程继承,本地变量不可以被子进程继承
六.获取环境变量
1.通过命令行第三个参数获取
这里先解释什么是命令行参数
先看代码:
#includeint main(int argc,char* argv[]){printf("%d\n",argc);for(int i=0;i
解释:命令行参数,其实是一个字符串,会把命令行参数以空格作为分隔符分割,将分割后的字符串的首地址放入 argv中,而argc是分割的个数。
而main函数的第三个参数是一个指向环境变量表的指针数组 char* env[],我们可以通过数组下标,最后一个是NULL,来访问环境变量。
#includeint main(int argc,char* argv[],char* env[]){for(int i=0;env[i]!=NULL;i++){printf("%s\n",env[i]);}return 0;}
注:
1.env是一个指针数组,记录的是每个环境变量的首地址。
2.证明环境变量可以被子进程继承
3.应证了环境变量的组织方式。
2.通过第三方变量environ获取
#includeint main(){extern environ;for(int i=0;environ[i];i++){printf("%s\n",environ[i]);}return 0;}
注意:
libc中定义的全局变量environ指向环境变量表,environ没有包含在任何头文件中,所以在使用时,要用extern声明。
3.通过系统调用getenv()
#include#includeint main(){char* a=getenv("PATH");printf("%s\n",a);return 0;}
注意:
1.环境变量通常具有全局属性,可以被子进程继承