马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
写 C/C++ 程序时经常好奇:链接阶段从没告诉编译器动态库在哪,它为什么照样找得到?答案藏在「环境变量」里。本文从 main 函数的第三个参数讲起,把 PATH、HOME、SHELL、PWD、USER 这几个最常用的变量一次梳理清楚,并说明环境变量与本地变量的区别。
环境变量是什么
main 函数的命令行参数通常写成 argc、argv、env 三个:
argc:命令行参数的个数。
argv:存放每个参数的具体数值。
env:环境变量表。
前两个参数让程序能根据传入参数做分支,也就实现了「同一条命令加不同选项」的效果;第三个参数 env 打印出来,就是一张环境变量表。
环境变量是操作系统里用来指定运行环境的参数,登录 shell 之后会作为环境变量表传给后续所有进程。它通常带两个特征:有明确的用途,并且在系统里具备全局属性。
PATH:命令的搜索路径
有没有想过,为什么执行自己编译的程序要写 ./xxx,而系统命令直接敲名字就行?因为系统执行指令时会去 /usr/bin 这类固定路径下找。shell 登录时,PATH 就告诉 shell 该去哪些目录里翻。
echo $PATH
PATH 里用冒号分隔多个路径。shell 运行一条命令时,会按冒号切分后逐个目录查找:全部找完还没找到就报 command not found,任意一个目录命中就会加载并执行。
所以把自己的可执行文件路径追加进 PATH,就不用再带路径了:
PATH=$PATH:/你的/目录
但这是内存里的临时修改,退出 shell 就没了。PATH 本质上是 shell 维护的一个内存变量,重新登录会恢复成配置文件里读到的初始值。想永久生效,就得写进配置文件(家目录下的 .bashrc)。
HOME:当前用户的家目录
HOME 保存当前用户的家目录,也就是用户登录进系统后的默认落脚点。用户登录时系统创建 bash,bash 读取相关配置文件来初始化 PATH 和 HOME,因此登录后默认就处在家目录下。
bash 本身也是进程,有自己的工作目录(cwd),它会用配置好的 HOME 来设置自己的 cwd。命令行里执行的命令都是 bash 的子进程,而子进程的进程控制块是从父进程拷过来的,所以子进程天然继承 bash 当前的工作路径。
SHELL、PWD、USER
SHELL:登录时启动的是哪一个 Shell,值通常是 /bin/bash。
PWD:保存当前进程所在的工作路径,进程可以据此新建或打开当前路径下的文件。
USER:当前的用户身份,程序里可用 getenv("USER") 来识别。
三种读取方式
除了通过命令行参数 env,程序里还能用系统接口读取:
getenv("USER")
另外系统还留了一个第三方变量 environ 直接指向环境变量表,它没有包含在任何头文件中,使用时需要自己 extern 声明。
环境变量的本质与全局属性
环境变量本质上就是一张表,表是一个字符指针数组,每个指针指向一个以 \0 结尾的环境字符串。
能在命令行里定义的东西并不都是环境变量——那是 shell 自己维护的本地变量。查看系统里全部变量用 set;把一个本地变量升级成环境变量用 export,可以先进定义再导出,也可以一步 export 变量=100。
变量一旦进入环境变量表,就能被其他进程访问。子进程会继承父进程的环境变量表和命令行参数,但不会继承本地变量表;在子进程里用 unset 加变量名可以取消某个环境变量。
既然能被子进程继承,也就能被子进程的子进程继承,相当于 bash 之后所有进程都看得见——这就是环境变量「全局属性」的来源。
小结
环境变量是一张由 shell 维护、由父进程向子进程传递的字符指针数组。理解它只需要抓住两点:命令查找靠 PATH,进程间继承靠的是环境变量表而不是本地变量表。其余变量用到再查即可。
qidao123.com企服评测-应用市场 编辑提示 |