【Linux手册】环境变量与命令行参数:贯穿系统与应用的隐形桥梁
目录
前言
环境变量
是什么
如何用
环境变量的全局属性
本地变量
命令分类
补充:命令行参数
前言
在登录Xshell后为什么我的默认在自己的家目录下?为什么运行自己写的可执行程序要加./而指令不需要加目录,他们本质不都是可执行程序吗?.....
这些问题都与环境变量相关,下面将介绍一些重要或常见的环境变量。
环境变量
是什么
环境变量是操作系统提供的一组key(名称)---value(内容)形式的变量,用于存储系统和应用程序的相关信息。对于不同的用户环境变量是不一样的。
如何用
env:显示所有环境环境变量。
echo +$环境变量名:显示指定的环境变量。
PATH
PATH环境变量:用来记录指令的搜索路径,当在命令行中输入指令的时候会默认到这些路径下去查找,这就是为什么指令不需要加路径,而自己的可执行程序需要加路径。
环境变量也是变量,那么其一定也能进行修改,环境变量 = 修改后的内容.对环境变量进行修改;
如上对PATH路径进行修改后,ll和clear找不到命令了,并且test.eve的运行也不需要加./了,这就说明指令查找的默认路径确实被修改了。
上面对环境变量进行修改类似与覆盖,而有时我们希望的是追加此时可以使用 环境变量=$环境变量:增加的内容实现。
以上修改都没有写入到配置文件中,所以在重新打开Xshell后环境变量又会恢复为默认值。
HOME
HOME环境变量中存储这一个用户登录时的默认所处路径。正是因为HOME环境变量才使得不同用户进入Xshell后所处的目录不同。
char* getenv(char*)
char* getenv(const char* name)系统调用接口,可以通过代码来获取环境变量。
对于不同的用户其环境变量是不一样的,所以可以通过在程序中对设置环境变量实现对不同用户返回不同结果的功能。
第三方变量environ获取环境变量
extern char** environ;
环境变量的全局属性
环境变量具有全局属性:每一个进程都有环境变量,每一个进程都能找到或使用环境变量;
bash命令行解释器是我们在打开Xshell时自动加载的进程,bash会从操作系统的配置文件中读取环境变量信息,我们知道在命令行上启动的每一个进程都是bash的子进程,子进程会继承父进程的一些信息,其中就包含环境变量,这就是每一个进程都能获取环境变量的原因。
本地变量
与环境变量不同的是本地变量不具有全局属性,本地变量只有bash自己能够使用,子进程不会继承。
通过set可以显示所有本地变量+环境变量。
本地变量=设置值:增加或修改本地变量。
export + 本地变量:将本地变量修改为环境变量;
export + 本地变量=设置值:直接设置本地变量;
unset + 本地变量/环境变量:将本地变量或环境变量删除。
echo+ $本地变量:显示本地变量。
命令分类
子进程不会继承bash的本地变量,那么echo是一个指令,也是一个可执行程序,其不会继承bash的本地变量,请问:echo+$本地变量,echo能够打印出本地变量,那他的本地变量从何而来???
原因在于命令分为两大类:
- 常规命令:我们在命令行中执行的一些自己的可执行程序,需要bash创建子进程执行;
- 内建命令:由bash自己来执行,不需要创建子进程;类似于bash调用自己的函数或系统接口。
显而易见echo一定就是内建命令了,由bash命令行自己执行,这样就能获取到本地变量的。
实际上cd命令也是一个内建命令,否则如果cd执行时bash也创建了子进程,那么只会修改子进程的路径(进程间具有独立性),bash命令行解释器的路径是不会被修改的,而事实恰恰相反;bash通过调用chdir()系统调用接口来实现路径的修改。
补充:命令行参数
我们日常编写代码时使用的main函数实际上是可以传参的,int main(int argc,char* agrv[])其中argc表示参数的个数,argv[]分别存储传过来的参数。
有了命令行参数之后,就为指令,工具,可执行程序等提供了命令行选项的支持,这也是我们可以在指令后增加选项的原因。
指令 --help查看指令可以使用的选项。
main函数还有第三个参数,但是一般使用较少,是char** env环境变量参数。
main函数参数中有两个核心向量表:
- 命令行参数表;
- 环境变量表。
不论是命令行参数表还是环境变量表,其最后一个位置存放的都是NULL,表示空;所以在循环结束条件中可以使用argv[i]以及env[i]来进行判断,而不用写具体次数。