环境变量在Linux系统中的用途很多。你现在已经知道如何修改系统环境变量,也知道了如
何创建自己的环境变量。接下来的问题是怎样让环境变量的作用持久化。
在你登入Linux系统启动一个bash shell时,默认情况下bash会在几个文件中查找命令。这些
文件叫作启动文件或环境文件。bash检查的启动文件取决于你启动bash shell的方式。启动bash
shell有3种方式:
登录时作为默认登录shell
作为非登录shell的交互式shell
作为运行脚本的非交互shell
下面几节介绍了bash shell在不同的方式下启动文件。
6.6.1 登录 shell
当你登录Linux系统时,bash shell会作为登录shell启动。登录shell会从5个不同的启动文件里
读取命令:
/etc/profile
$HOME/.bash_profile
$HOME/.bashrc
$HOME/.bash_login
$HOME/.profile
/etc/profile文件是系统上默认的bash shell的主启动文件。系统上的每个用户登录时都会执行
这个启动文件。
说明
要留意的是有些Linux发行版使用了可拆卸式认证模块(Pluggable Authentication
Modules ,PAM)。在这种情况下,PAM文件会在bash shell启动之前处理,这些文件中可
能会包含环境变量。PAM文件包括 /etc/environment 文件和 $HOME/.pam_environment 文件。
PAM更多的相关信息可以在http://linux-pam.org中找到。
另外4个启动文件是针对用户的,可根据个人需求定制。我们来仔细看一下各个文件。
1. /etc/profile文件
/etc/profile文件是bash shell默认的的主启动文件。只要你登录了Linux系统,bash就会执行
/etc/profile 启动文件中的命令。不同的Linux发行版在这个文件里放了不同的命令。在本书所用的
Ubuntu Linux系统上,它看起来是这样的:
$ cat /etc/profile
# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
# and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).
if [ "$PS1" ]; then
if [ "$BASH" ] && [ "$BASH" != "/bin/sh" ]; then
# The file bash.bashrc already sets the default PS1.
# PS1='\h:\w\$ '
if [ -f /etc/bash.bashrc ]; then
. /etc/bash.bashrc
fi
else
if [ "`id -u`" -eq 0 ]; then
PS1='# '
else
PS1='$ '
fi
fi
fi
# The default umask is now handled by pam_umask.
# See pam_umask(8) and /etc/login.defs.
if [ -d /etc/profile.d ]; then
for i in /etc/profile.d/*.sh; do
if [ -r $i ]; then
. $i
fi
done
unset i
fi
$
这个文件中的大部分命令和语法都会在第12章以及后续章节中具体讲到。每个发行版的
/etc/profile文件都有不同的设置和命令。例如,在上面所显示的Ubuntu发行版的/etc/profile文件中,
涉及了一个叫作/etc/bash.bashrc的文件。这个文件包含了系统环境变量。
但是,在下面显示的CentOS发行版的/etc/profile文件中,并没有出现这个文件。另外要注意
的是,该发行版的/etc/profile文件还在内部导出了一些系统环境变量。
$ cat /etc/profile
# /etc/profile
# System wide environment and startup programs, for login setup
# Functions and aliases go in /etc/bashrc
# It's NOT a good idea to change this file unless you know what you
# are doing. It's much better to create a custom.sh shell script in
# /etc/profile.d/ to make custom changes to your environment, to
# prevent the need for merging in future updates.
pathmunge () {
case ":${PATH}:" in
*:"$1":*)
;;
*)
if [ "$2" = "after" ] ; then
PATH=$PATH:$1
else
PATH=$1:$PATH
fi
esac
}
if [ -x /usr/bin/id ]; then
if [ -z "$EUID" ]; then
# ksh workaround
EUID=`id -u`
UID=`id -ru`
fi
USER="`id -un`"
LOGNAME=$USER
MAIL="/var/spool/mail/$USER"
fi
# Path manipulation
if [ "$EUID" = "0" ]; then
pathmunge /sbin
pathmunge /usr/sbin
pathmunge /usr/local/sbin
else
pathmunge /usr/local/sbin after
pathmunge /usr/sbin after
pathmunge /sbin after
fi
HOSTNAME=`/bin/hostname 2>/dev/null`
HISTSIZE=1000
if [ "$HISTCONTROL" = "ignorespace" ] ; then
export HISTCONTROL=ignoreboth
else
export HISTCONTROL=ignoredups
fi
export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL
# By default, we want umask to get set. This sets it for login shell
# Current threshold for system reserved uid/gids is 200
# You could check uidgid reservation validity in
# /usr/share/doc/setup-*/uidgid file
if [ $UID -gt 199 ] && [ "`id -gn`" = "`id -un`" ]; then
umask 002
else
umask 022
fi
for i in /etc/profile.d/*.sh ; do
if [ -r "$i" ]; then
if [ "${-#*i}" != "$-" ]; then
. "$i"
else
. "$i" >/dev/null 2>&1
fi
fi
done
unset i
unset -f pathmunge
$
录下的所有文件。(该语句会在第13章中详述。)这为Linux系统提供了一个放置特定应用程序启
动文件的地方,当用户登录时,shell会执行这些文件。在本书所用的Ubuntu Linux系统中,
/etc/profile.d目录下包含以下文件:
$ ls -l /etc/profile.d
total 12
-rw-r--r-- 1 root root 40 Apr 15 06:26 appmenu-qt5.sh
-rw-r--r-- 1 root root 663 Apr 7 10:10 bash_completion.sh
-rw-r--r-- 1 root root 1947 Nov 22 2013 vte.sh
$
在CentOS系统中,/etc/profile.d目录下的文件更多:
$ ls -l /etc/profile.d
total 80
-rw-r--r--. 1 root root 1127 Mar 5 07:17 colorls.csh
-rw-r--r--. 1 root root 1143 Mar 5 07:17 colorls.sh
-rw-r--r--. 1 root root 92 Nov 22 2013 cvs.csh
-rw-r--r--. 1 root root 78 Nov 22 2013 cvs.sh
-rw-r--r--. 1 root root 192 Feb 24 09:24 glib2.csh
-rw-r--r--. 1 root root 192 Feb 24 09:24 glib2.sh
-rw-r--r--. 1 root root 58 Nov 22 2013 gnome-ssh-askpass.csh
-rw-r--r--. 1 root root 70 Nov 22 2013 gnome-ssh-askpass.sh
-rwxr-xr-x. 1 root root 373 Sep 23 2009 kde.csh
-rwxr-xr-x. 1 root root 288 Sep 23 2009 kde.sh
-rw-r--r--. 1 root root 1741 Feb 20 05:44 lang.csh
-rw-r--r--. 1 root root 2706 Feb 20 05:44 lang.sh
-rw-r--r--. 1 root root 122 Feb 7 2007 less.csh
-rw-r--r--. 1 root root 108 Feb 7 2007 less.sh
-rw-r--r--. 1 root root 976 Sep 23 2011 qt.csh
-rw-r--r--. 1 root root 912 Sep 23 2011 qt.sh
-rw-r--r--. 1 root root 2142 Mar 13 15:37 udisks-bash-completion.sh
-rw-r--r--. 1 root root 97 Apr 5 2012 vim.csh
-rw-r--r--. 1 root root 269 Apr 5 2012 vim.sh
-rw-r--r--. 1 root root 169 May 20 2009 which2.sh
$
不难发现,有些文件与系统中的特定应用有关。大部分应用都会创建两个启动文件:一个供
bash shell使用(使用.sh扩展名),一个供c shell使用(使用.csh扩展名)。
lang.csh和lang.sh文件会尝试去判定系统上所采用的默认语言字符集,然后设置对应的 LANG
环境变量。
2. $HOME目录下的启动文件
剩下的启动文件都起着同一个作用:提供一个用户专属的启动文件来定义该用户所用到的环
境变量。大多数Linux发行版只用这四个启动文件中的一到两个:
$HOME/.bash_profile
$HOME/.bashrc
$HOME/.bash_login
$HOME/.profile
注意,这四个文件都以点号开头,这说明它们是隐藏文件(不会在通常的 ls 命令输出列表中
出现)。它们位于用户的HOME目录下,所以每个用户都可以编辑这些文件并添加自己的环境变
量,这些环境变量会在每次启动bash shell会话时生效。
说明 Linux发行版在环境文件方面存在的差异非常大。本节中所列出的$HOME下的那些文件并
非每个用户都有。例如有些用户可能只有一个$HOME/.bash_profile文件。这很正常。
shell会按照按照下列顺序,运行第一个被找到的文件,余下的则被忽略:
$HOME/.bash_profile
$HOME/.bash_login
$HOME/.profile
注意,这个列表中并没有$HOME/.bashrc文件。这是因为该文件通常通过其他文件运行的。
窍门 记住,$HOME表示的是某个用户的主目录。它和波浪号(~)的作用一样。
CentOS Linux系统中的.bash_profile文件的内容如下:
$ cat $HOME/.bash_profile
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/bin
export PATH
$