登录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 Moudules ,PAM)在这种情况下,PAM文件会在bash shell启动之前处理,这些文件中可能会包含环境变量。PAM文件包括/etc/environment文件和$HOME/.pam_environment文件。PAM更多的相关信息可以在http://linux-pam.org中找到。
另外4个启动文件是针对用户的,可根据个人需求定制。我们来仔细看一下各个文件。
- etc/profile文件
/etc/profile文件是默认的主启动文件。只要你登录了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/bsh.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
$
例如在上面显示的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
# Function 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 changers 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
#Path manipulation
if [ "$EUID" = "0" ]; then
pathmunge /sbin
pathmunge /usr/sbin
pathmunge /usr/local/sbin
else
pathmunge /usr/local/sbin after
pathmunage /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
# /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
."$i"
else
. "$i" >/dev/null 2>&1
fi
fi
done
unset i
unset -f patmunge
$
这两个发行版的/etc/profile文件都用到了一个共同的特性:for语句。它用来迭代/etc/profile.d目录下的所有文件。这为Linux系统提供了一个防止特定应用程序启动文件的地方,当用户登录时,shell会执行这些文件。