一、什么是环境变量
环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数,如:我们在编写C/C++代码时,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。环境变量通常具有某些特殊用途,在系统当中通常具有全局特性。
二、环境变量的类别与作用
- echo:显示某个环境变量值
- export:设置一个新的环境变量
- env:显示所有环境变量
- unset:清除环境变量
- set:显示本地定义的shell变量和环境变量
输入以下的指令,可以看到系统的环境变量:
env
[wangchen@VM-4-5-centos ~]$ env
XDG_SESSION_ID=408982
HOSTNAME=VM-4-5-centos
TERM=xterm
SHELL=/bin/bash
HISTSIZE=3000
SSH_CLIENT=183.198.108.21 18597 22
SSH_TTY=/dev/pts/0
USER=wangchen
LD_LIBRARY_PATH=:/home/wangchen/.VimForCpp/vim/bundle/YCM.so/el7.x86_64
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:
MAIL=/var/spool/mail/wangchen
PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/wangchen/.local/bin:/home/wangchen/bin
PWD=/home/wangchen
LANG=en_US.utf8
SHLVL=1
HOME=/home/wangchen
LOGNAME=wangchen
SSH_CONNECTION=183.198.108.21 18597 10.0.4.5 22
LESSOPEN=||/usr/bin/lesspipe.sh %s
PROMPT_COMMAND=history -a; history -a; printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"
XDG_RUNTIME_DIR=/run/user/1002
HISTTIMEFORMAT=%F %T
_=/usr/bin/env
以上所有环境变量都是当前用户登陆时,Linux为当前用户定制的。
其中常见环境变量有如下几种:
- PATH:指定命令的搜索路径
- HOME:指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
- SHELL:当前Shell,它的值通常是/bin/bash。
我们可以通过以下指令来查看环境变量:
echo $[环境变量]
1、PATH
我们所写的代码编译生成可执行程序后,为什么在运行时必须要加上 ./ 呢?为什么同为可执行程序的 ls 、 pwd 等等诸多指令在使用时不需要加 ./ 呢?尽管他们在本质上完全相同。

编译运行,现象如下:

之所以要加上 ./ ,是因为在程序运行时,需要说明该可执行程序所处的路径,执行一个命令的前提是先找到它。如果我们愿意,也可以使用绝对路径来说明:

接下来回答第二个问题,为什么同为可执行程序的 ls 、 pwd 等等诸多指令在使用时不需要加 ./ 来说明其所处路径呢?这是因为在系统中存在一个环境变量帮助我们在特定路径下搜索这些默认指令,这个环境变量叫做 PATH 。
使用指令 echo $PATH 来查看该环境变量:

可以发现在环境变量 PATH 中指明了由 ":" 分割开来的若干个路径,我们在执行命令时,系统会自动在这些路径中从前向后依次寻找,找到了就自动执行,而不需要人为说明其所在路径。
使用 which 指令来查看部分系统默认指令所处的路径:

可以看到 ls 与 pwd 的路径刚好被包括在 PATH 之中。
解决了如上两个问题后,我们该如何让自己编写的可执行程序在运行时也不需要加上其路径呢?很简单,只需要把自己的可执行程序的路径添加到 PATH 中就可以了,使用命令:
export PATH=$PATH:[想加入程序的路径]

如此一来,便可以直接执行自己的可执行程序了。环境变量会在xshell重新打开时被恢复初始状态,所以大家也不用担心在设置环境变量时出现错误。
除了这一种做法以外,我们还可以把自己的可执行程序拷贝到 PATH 中本来就有的路径当中去,达到相同的效果,这里不再演示。
实际上,在Linux中,把可执行程序拷贝到系统默认路径下,让我们可以直接访问的方式,就相当于Linux下软件的安装。把可执行程序从系统默认路径下删除,就相当于软件的卸载。
2、HOME
HOME 环境变量代表当前登录用户的家目录,对比普通用户与root用户的 HOME 环境变量:

发现 HOME 环境变量是不同的。这说明对于不同的登录用户,同一个环境变量可能存放不同的数据,即环境变量是针对特定的人,在特定的场景中被使用的变量。
三、获取环境变量
main 函数的形参列表最多可以带有 3 个参数,分别为 argc 、 argv 、 envp :
int main(int argc, char* argv[], char* envp[])
{}
其中 char* envp[] 是一个指针数组,该数组里面的指针都分别指向不同的字符串,并且最后一个指向有效字符串的指针的下一个指针一定指向 "NULL" 。

构成了上图所示的表结构形式。
编写如下程序:


发现这些指针指向的就是一个一个环境变量字符串。
讲到这里,我们的C/C++素养让我们意识到当函数传参数组时,传递的不是数组本身,而是数组首元素地址,所以在 main 函数的形参列表中写成的 char* envp[] 形式,本质上是一个二级指针,名为 environ ,查看一下 man 手册:
man environ

最终,可以得知这个表状结构的具体示意图为:

以后想要获取环境变量就可以通过遍历这个表状结构体获取了。
但是这样做的话太过于麻烦,为了方便起见,主流的获取环境变量的方法是通过函数获取,该函数名为 getenv 。
使用 man 手册查看该函数:
man getenv

可知其用法为:
getenv("[环境变量名]")


5290

被折叠的 条评论
为什么被折叠?



