1. 基本概念
Linux
操作系统本身就是一个用C语言写的程序,因此操作系统可以在运行的过程中开辟空间。环境变量的本质,就是操作系统运行过程中,为自己开辟的空间,存储了一些重要的信息。
2. 常见环境变量
1. PATH : 指定命令的搜索路径
PATH
:一个环境变量,存储着多个路径,在这些路径下面的可执行程序,可以直接执行
我们可以通过echo $xxx
查看xxx
环境变量的内容,接下来,我们可以通过echo $PATH 来查看PATH中的内容
它的内容是由一串路径+冒号+另一串路径+冒号+…。它用冒号作为分割符,定义出了许多路径。当在命令行输入指令时,操作系统会默认到这些路径下去查找,如果都没有找到,就会报错。那么像ls等指令在执行时就会在PATH里挨个寻找路径,执行正确的路径;而我们自己的可执行程序的路径并不在定义里,所以需要加./。我们也可以将自己的可执行程序的路径添加到PATH里。
例如我们有一个test程序,输入指令 ./test 执行后输出hello world.
该程序处于路径 /home/lbk/lesson5 ,我们可以通过指令 PATH=$PATH:/home/lbk/lesson5 来将其添加到PATH的环境变量中,这样之后我们就可以通过直接输入指令 test来执行test程序。注意不能用命令PATH=/home/lbk/lesson5,这样会覆盖掉原有的环境变量,只剩下/home/lbk/lesson5 ,可以再次查看PATH的内容
2. HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
为什么当一个用户登陆时会自动到它的家目录里呢?这是因为当你登陆xshell时,xshell会自动识别用户,然后填充该用户的HOME变量。
3.SHELL:当前Shell,它的值通常是/bin/bash
通过$SHELL可以看到当前shell的可执行程序。
3. 查看环境变量的方法
1. env指令
env
:输出所有环境变量
2. getenv函数
getenv
是一个函数,其定义在<stdlib.h>
中,功能是:输入一个字符串作为参数,该函数输出该字符串对应的环境变量。
在test.c中我们写下以下程序并运行
3. environ
environ是一个外部的变量,只需要extern后就可以直接使用,本质是一个char*的数组,也就是说其类型为char* []或者char**。environ的每个元素都是char*指针,指向一个字符串,字符串内部存储的就是环境变量。而environ的最后一个元素是NULL,用于帮助程序员判断什么时候数组到了结尾。例如,在test.c中我们写下以下程序并运行
4. 命令行参数
也许你听说过,main
函数也是有参数的,但是在C/C++
学习中,这个参数好像可写可不写,学习环境变量后,我们就可以了解一下这些变量的意义是什么了。
可见,argc是int类型的变量,argc代表argv里的元素个数,argv是一个char*的数组,argv每个元素都是char*类型,分别指向一个字符串,argv的最后一个元素也是NULL,用于标识argv的数组结尾。接下来我们把argv内容打印出来看看。
main函数在用户层面上看是入口函数,但实际上main函数并不是第一个被调用的函数,它会先被其他函数调用,而argc,argv就是传的参。在我们看来我们输入的是./test -a但bash实际上是以空格为分隔符直接解释成了"./test" "-a"两个字符串。再把字串的个数存入argc,每个子串的首地址保存在argv里。将字符串打散这一过程就是命令行解析。所以可以通过判定argv[ i ]的值就可以执行不同的操作,故而命令行参数有一个重要功能就是为指令提供多个选项。
在我们向bash
输入一大段指令的时候,指令本质就是一个字符串,bash
会把字符串拆解为一个个小的字符串,然后把它们整合到一个叫做命令行参数表
的东西中,命令行参数表
其实就是一个指针数组char* []
,而argv
参数就可以接收这个bash
维护的数组,在程序内部读取。
事实上,main还有第三个参数char* env[ ],其内部存储了环境变量,以及环境变量的值.我们可以将其内容输出看看。
我们直接遍历env[]也可以获得全部的环境变量。并且我们可以发现这里的环境变量与env指令里的环境变量一模一样,所以其实我们写的程序的环境变量是继承于父进程的。这也是为什么环境变量具有全局性。
所有在命令行调用的进程,都是bash
的子进程,因此我们的在命令行调用的进程可以继承到bash
的环境变量表。其实这些环境变量是被存在磁盘中的,而我们启动bash的时候,会把这些环境变量从磁盘中拷贝到内存中,组成一个环境变量表。我们访问环境变量,都是在访问内存中的环境变量。我们修改环境变量,也是在修改内存中的环境变量。而当我们重启shell,那么bash就会重新去磁盘拷贝一份环境变量,我们之前对环境变量的所有修改,都没有影响磁盘中的环境变量,因此我们重启的时候,可以重置环境变量。
结论:我们所运行的进程,都是子进程,bash本身在启动的时候,会从操作系统的配置文件中读取环境变量信息,子进程会继承父进程交给我的环境变量!
5. 环境变量增加和删除
增加
我们可以通过 export 指令来定义新的环境变量,不过自己定义的环境变量,在xshell
重启的时候,也会失效。
删除
我们可以通过 unset指令来删除环境变量
6. 本地变量
本地变量就是我们可以直接在命令行里定义的变量,本地变量只在本BASH内部有效,不会继承。
我们可以通过set指令可以查看所有变量包括环境变量和本地变量