bash配置文件的加载顺序和登陆方式有关,下面先介绍下登陆方式。
1 登陆方式有2种
登陆式SHELL:
- su - oracle
- su -l oracle
- 正常从终端登陆
非登录式SHELL:
- su oracle
- 图形终端打开命令窗口
- 自动执行的shell脚本
2 bash配置文件的分两大类
- 全局配置:/etc/profile, /etc/profile.d/*.sh, /etc/bashrc
- 个人配置:~/.bash_profile, ~/.bashrc
profile类文件作用
- 定义环境变量
- 运行命令或者脚本
bashrc类文件作用
- 定义本地变量,函数
- 命令别名
3 加载顺序
登陆式SHELLL配置文件加载顺序:/etc/profile > .bash_profile > .bash_login > .profile > .bash_logout.
非登录式SHELL配置文件加载顺序:/etc/bash.bashrc > .bashrc
注: 先加载的配置文件的配置,可能会被后加载的配置所覆盖
下面一张图展示下加载顺序, A >B1>B2>B2>C
4 主要代码分析
4.1 在/etc/profile文件中, 我们可以看到如下代码
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
简单的说,我们的/etc/profile这个文件进行一系列的设置后, 最后需要遍历下/etc/profile.d这个目录下的所有sh文件, 然后source每个文件,让每个文件的设置生效。
4.2 在~/.bash_profile文件中,我们可以看到如下代码
[root@centos6 ~]# cat ~/.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
我们可以看出来,在~/.bash_profile文件中, 判断了~/.bashrc文件是不是存在,如果存在,也source下,让其生效。
4.3 在~/.bashrc文件中,我们可以看到如下代码
[root@centos6 ~]# cat ~/.bashrc # .bashrc # User specific aliases and functions alias rm='rm -i' alias cp='cp -i' alias mv='mv -i' # Source global definitions if [ -f /etc/bashrc ]; then . /etc/bashrc fi
我们可以看出来,先设置了一些自定义的别名设置,然后去source了/etc/bashrc这个文件。
4.4 在/etc/bashrc文件中, 我们可以看到如下代码
if ! shopt -q login_shell ; then # We're not a login shell # Need to redefine pathmunge, it get's undefined at the end of /etc/profile pathmunge () { case ":${PATH}:" in *:"$1":*) ;; *) if [ "$2" = "after" ] ; then PATH=$PATH:$1 else PATH=$1:$PATH fi esac } # By default, we want umask to get set. This sets it for non-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 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then umask 002 else umask 022 fi # Only display echos from profile.d scripts if we are no login shell # and interactive - otherwise just process them to set envvars for i in /etc/profile.d/*.sh; do if [ -r "$i" ]; then if [ "$PS1" ]; then . "$i" else . "$i" >/dev/null 2>&1 fi fi done unset i unset pathmunge fi
我们可以看到,最后一部分代码表示在非登录shell中, /etc/bashrc文件会source /etc/prifile.d目录下的所有sh文件。