6. 环境变量
6.a. 环境变量?
是什么?
环境变量是一个已命名的对象 (named object), 它包含了让一个或多个应用程序使用的一些信息. 许多用户 (尤其是 Linux 的新用户) 会觉得这东西似乎颇为诡异或难以捉摸 (a bit weird or unmanageable). 这感觉是不对的: 使用环境变量, 我们可以轻松地改变一个或多个应用程序的配置.
重要的例子
下表给出了 Linux 系统中所用的好些环境变量及其描述. 其示例值在表后给出.
变量 | 描述 |
PATH | 该变量包含了一个以冒号分隔的目录列表以让系统在这些目录里寻找可执行文件. 如果您输入了一个可执行文件的名字 (如 ls, rc-update 或 emerge), 而该文件却不在这一列表中的任一目录里, 则您的系统将不会执行它 (除非您输入完整的路径, 如 /bin/ls) |
ROOTPATH | 该变量共同与 PATH 同, 不过它仅列出根用户 (root-user) 输入一个命令时应该寻找的目录. |
LDPATH | 该变量包含了一个以冒号分隔的目录列表以让动态链接器 (dynamical linker) 在这些目录里寻找库文件 (library). |
MANPATH | 该变量包含了一个以冒号分隔的目录列表以让 man 命令在这些目录里寻找手册页 |
INFODIR | 该变量包含了一个以冒号分隔的目录列表以让 info 命令在这些目录里选择信息页 |
PAGER | 该变量包含了用以查看文件内容的程序 (如 less 或 more) 所在的路径 |
EDITOR | 该变量包含了用以编辑文件内容的程序 (如 nano 或 vi) 所在的路径 |
KDEDIRS | 该变量包含了一个以冒号分隔的目录列表, 这些目录里包含了 KDE 专用的东西 |
CLASSPATH | 该变量包含了一个以冒号分隔的目录列表, 这些目录里包含了 Java 类 |
CONFIG_PROTECT | 该变量包含了一个以空格分隔的目录列表, 这些目录是 Portage 在更新时需要进行保护的 |
CONFIG_PROTECT_MASK | 该变量包含了一个以空格分隔的目录列表, 这些目录是 Portage 在更新时无须进行保护的 |
下面给出这些变量的示例定义:
代码清单 1: 示例定义 |
PATH="/bin:/usr/bin:/usr/local/bin:/opt/bin:/usr/games/bin" ROOTPATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin" LDPATH="/lib:/usr/lib:/usr/local/lib:/usr/lib/gcc-lib/i686-pc-linux-gnu/3.2.3" MANPATH="/usr/share/man:/usr/local/share/man" INFODIR="/usr/share/info:/usr/local/share/info" PAGER="/usr/bin/less" EDITOR="/usr/bin/vim" KDEDIRS="/usr" CLASSPATH="/opt/blackdown-jre-1.4.1/lib/rt.jar:." CONFIG_PROTECT="/usr/X11R6/lib/X11/xkb /opt/tomcat/conf \ /usr/kde/3.1/share/config /usr/share/texmf/tex/generic/config/ \ /usr/share/texmf/tex/platex/config/ /usr/share/config" CONFIG_PROTECT_MASK="/etc/gconf |
6.b. 定义全局变量
/etc/env.d 目录
为了集中管理 (centralize) 这些变量的定义, Gentoo 包含了一个 /etc/env.d 目录. 该目录中您会看到数个文件, 如 00basic, 05gcc 等等. 这些文件包含了其命名中所提到的应用程序所需的环境变量 (which contain the variables needed by the application mentioned in their name) (Cure: 如 05gcc 里带的是 gcc 要用的环境变量, 10mozilla 带的是 mozilla 要用的环境变量, 20java 里是 java 要用的环境变量, 依此类推).
例如, 您安装完 gcc 之后, gcc 的 ebuild 就会创建一个名为 05gcc 的文件, 里面包含了如下变量的定义:
代码清单 2: /etc/env.d/05gcc |
PATH="/usr/i686-pc-linux-gnu/gcc-bin/3.2" ROOTPATH="/usr/i686-pc-linux-gnu/gcc-bin/3.2" MANPATH="/usr/share/gcc-data/i686-pc-linux-gnu/3.2/man" INFOPATH="/usr/share/gcc-data/i686-pc-linux-gnu/3.2/info" CC="gcc" CXX="g++" LDPATH="/usr/lib/gcc-lib/i686-pc-linux-gnu/3.2.3" |
其他发行版会让您在 /etc/profile 或其他某个地方修改或添加这样那样的环境变量, 而 Gentoo 为您 (也为 Portage) 提供了一个很轻松的方式来维护和管理它们, 同时无须关心那些都可以包含环境变量的诸多文件.
例如, 当 gcc 更新时, /etc/env.d/05gcc 同时更新而无须用户操心.
这不仅让 Portage 受益, 还包括您, 作为一个用户. 不时地, 您会需要设定某个应用到系统范围的环境变量. 我们以 http_proxy 变量为例. 我们不必去 /etc/profile 里乱搞, 仅需创建一个文件 (/etc/env.d/99local) 并把定义写里面就搞定:
代码清单 3: /etc/env.d/99local |
http_proxy="proxy.server.com:8080" |
以同一个文件来放置您的所有变量, 您就可以很容易地知道自己都定义了哪些变量.
env-update 脚本
数个 /etc/env.d 中的文件里都定义了 PATH 变量, 这没有问题的: 当您运行 env-update, 它会在更新环境变量之前会先把这些定义添加到一起, 籍此可以让软件包 (或用户) 很轻松地添加自己的环境变量而无须担心干扰到原有的值.
env-update 脚本会将 /etc/env.d 下的文件按字母顺序逐个添加它们里面的值. 这就是为什么 /etc/env.d 下的许多文件都以数字开头.
代码清单 4: env-update 的更新顺序 |
00basic 99kde-env 99local +-------------+----------------+-------------+ PATH="/bin:/usr/bin:/usr/kde/3.2/bin:/usr/local/bin" |
运行 env-update 的时候, 该脚本创建所有环境变量并将它们放在 /etc/profile.env 文件中 (为 /etc/profile 所用). 同时, 它还从 LDPATH 变量中提取信息以创建 /etc/ld.so.conf. 之后, 它将运行 ldconfig 以重新创建为动态链接器 (dynamical linker) 所用的 /etc/ld.so.cache 文件.
如果您想在运行 env-update 之后马上看到效果, 请运行如下命令来更新您的环境. 自己装过 Gentoo 的用户想必对安装指南中的这句并不陌生:
代码清单 5: 更新环境 |
# env-update && source /etc/profile |
6.c. 定义局部变量
用户特定
您并非总想全局性地定义某个变量. 例如, 您或许想让 /home/my_user/bin 成为 PATH 变量里的一部分, 而同时又不没必要让系统中的其他用户的 PATH 里有这个路径. 您要想局部地定义变量, 请使用 ~/.bashrc 或 ~/.bash_profile 文件:
代码清单 6: 在 ~/.bashrc 中扩展 PATH 变量以供局部 (Cure: 只对本用户有用) 使用 |
PATH="${PATH}:/home/my_user/bin" |
您重新登录后, PATH 变量就会被更新.
会话特定
有时我们还需要定义范围更狭窄 (stricter) 的变量. 您也许想使用自己临时创建目录中的一些 (可执行的) 二进制文件, 而又不想总输入它们的完整路径, 也不想就为了这么一小会儿的使用而去编辑 ~/.bashrc.
这种情况下, 您可以用 export 命令在您当前的会话中定义 PATH 变量. 只要您未曾注销, 则 PATH 变量会一直使用该临时值.
代码清单 7: 定义会话特定 (session-specific) 的环境变量 |
# export PATH="${PATH}:/home/my_user/tmp/usr/bin" |