bash shell用一个叫作环境变量(environment variable)的特性来存储有关shell会话和工作环
境的信息(这也是它们被称作环境变量的原因)。这项特性允许你在内存中存储数据,以便程序
或shell中运行的脚本能够轻松访问到它们。这也是存储持久数据的一种简便方法。
在bash shell中,环境变量分为两类:

  • 全局变量
  • 局部变量

本节将描述以上环境变量,并演示怎么查看和使用它们。


说明 尽管bash shell使用一致的专有环境变量,但不同的Linux发行版经常会添加其自有的环境
变量。你在本章中看到的环境变量的例子可能会跟你安装的发行版中看到的结果略微不
同。如果遇到本书未讲到的环境变量,可以查看你的Linux发行版上的文档。


6.1.1 全局环境变量

全局环境变量对于shell会话和所有生成的子shell都是可见的。局部变量则只对创建它们的
shell可见。这让全局环境变量对那些所创建的子shell需要获取父shell信息的程序来说非常有用。

Linux系统在你开始bash会话时就设置了一些全局环境变量(如想了解此时设置了哪些变量,
请参见6.6节)。系统环境变量基本上都是使用全大写字母,以区别于普通用户的环境变量。

要查看全局变量,可以使用env或printenv命令。

$ printenv
HOSTNAME=server01.class.edu
SELINUXROLE_REQUESTED=
TERM=xterm
SHELL=/bin/bash
HISTSIZE=1000
[…]
HOME=/home/Christine
LOGNAME=Christine
[…]
G_BROKEN_FILENAMES=1
=/usr/bin/printenv

系统为bash shell设置的全局环境变量数目众多,我们不得不在展示的时候进行删减。其中有
很多是在登录过程中设置的,另外,你的登录方式也会影响到所设置的环境变量。

要显示个别环境变量的值,可以使用printenv命令,但是不要用env命令。

$ printenv HOME
/home/Christine
$
$ env HOME
env: HOME: No such file or directory
$

也可以使用echo显示变量的值。在这种情况下引用某个环境变量的时候,必须在变量前面
加上一个美元符($)。

$ echo $HOME
/home/Christine
$

在echo命令中,在变量名前加上$可不仅仅是要显示变量当前的值。它能够让变量作为命令
行参数。

$ ls $HOME Desktop Downloads Music Public test.sh
Documents junk.dat Pictures Templates Videos
$
$ ls /home/Christine
Desktop Downloads Music Public test.sh
Documents junk.dat Pictures Templates Videos
$

正如前面提到的,全局环境变量可用于进程的所有子shell。

$ bash
$
$ ps -f

UID PID PPID C STIME TTY TIME CMD

501 2017 2016 0 16:00 pts/0 00:00:00 -bash

501 2082 2017 0 16:08 pts/0 00:00:00 bash

501 2095 2082 0 16:08 pts/0 00:00:00 ps -f

$

$ echo $HOME

/home/Christine

$

$ exit

exit

$

在这个例子中,用bash命令生成一个子shell后,显示了HOME环境变量的当前值,这个值和
父shell中的一模一样,都是/home/Chrisine。

6.1.2 局部环境变量

顾名思义,局部环境变量只能在定义它们的进程中可见。尽管它们是局部的,但是和全局环
境变量一样重要。事实上,Linux系统也默认定义了标准的局部环境变量。不过你也可以定义自
己的局部变量,如你所想,这些变量被称为用户定义局部变量。

查看局部环境变量的列表有点复杂。遗憾的是,在Linux系统并没有一个只显示局部环境
变量的命令。set命令会显示为某个特定进程设置的所有环境变量,包括局部变量、全局变量
以及用户定义变量。

$ set

BASH=/bin/bash

[…]

BASH_ALIASES=()

BASH_ARGC=()

BASH_ARGV=()

BASH_CMDS=()

BASH_LINENO=()

BASH_SOURCE=()

[…]

colors=/etc/DIR_COLORS

my_variable=’Hello World’

[…]

$

可以看到,所有通过printenv命令能看到的全局环境变量都出现在了set命令的输出中。
但在set命令的输出中还有其他一些环境变量,即局部环境变量和用户定义变量。


说明 命令env、printenv和set之间的差异很细微。set命令会显示出全局变量、局部变量以
及用户定义变量。它还会按照字母顺序对结果进行排序。env和printenv命令同set命
令的区别在于前两个命令不会对变量排序,也不会输出局部变量和用户定义变量。在这
种情况下,env和printenv的输出是重复的。不过env命令有一个printenv没有的功能,
这使得它要更有用一些。