Linux bash 启动配置
bash是默认的shell,有必要了解一下它不同启动方式下的配置过程。
当执行bash命令或者用户登录系统时,会陆续加载各种bash配置文件,还会设置或清空一系列变量,有时还会执行一些自定义的命令,这些行为都算是启动bash时的过程。在不同的系统中具体的逻辑还是不同的,目前只关注Ubuntu和CentOS。
启动过程有两个维度的分类方式:
- 交互式和非交互式
- 交互式的标准情景:输入一个命令,然后输出
user@host:path$
,等待用户输入; - 非交互式的标准情景:
bash
执行一个脚本,例如bash demo.sh
。
- 交互式的标准情景:输入一个命令,然后输出
- 登录和非登录:顾名思义,非登录情景可以加上
--login
或-l
选项来伪装为登录情况。
可以通过下面的方法进行判断:
- 交互式的判断:
- 交互式环境下的
$-
变量会含有字母i
; - 交互式定义了提示符
$PS1
,但是非交互式会清空这个变量,因此echo $PS1
可以区分。
- 交互式环境下的
- 登录和非登录的判断:
shopt login_shell
,返回on
或off
。
1 | echo $PS1;shopt login_shell |
使用ssh
命令时:
ssh
远程登录:交互式、登录式;ssh
远程执行命令但不登录:非交互式、非登录式
使用bash
命令启动shell时:
bash
:交互式、非登录式bash -l
:交互式、登录式
使用bash
命令执行脚本时:
bash demo.sh
:非交互式、非登录式bash -l demo.sh
:非交互式、登录式
使用su
命令切换用户时,加不加-
有不同的效果:
su user2
:切换到user2
,打开的shell是交互式、非登录式su - user2
:切换到user2
,打开的shell是交互式、登录式
在图形用户界面下打开终端时,默认为交互式、非登录式;但是可以在设置中改为交互式、登录式。
bash不同启动过程中涉及到的配置文件可能有
- 系统级:
/etc/profile
(通常在脚本中自动加载/etc/profile.d/*.sh
)/etc/bash.bashrc
/etc/bashrc
- 用户级:
~/.profile
~/.bash_profile
~/.bash_login
~/.bashrc
(通常用户只需要在这里进行修改)
bash退出时还涉及
~/.bash_logout
等文件,这里不做讨论。此外,~/.bash_history
文件记录了bash的历史命令。
对于一个交互式、登录式启动的shell,或者非交互式但是使用-l
选项的情况:
- 首先读取
/etc/profile
; - 然后依次搜索
~/.bash_profile
、~/.bash_login
和~/.profile
(在某些系统中,某个文件会自动生成,其它文件则默认不存在),仅加载其中第一个存在到且可读的文件。
使用--noprofile
可以跳过这个过程。如果这里使用的是sh
名称,出于兼容性考虑,只会依次加载etc/profile
和~/.profile
。
对于一个交互式、非登录式启动的shell:
- 读取
/etc/bash.bashrc
和~/.bashrc
;
对于一个非交互式、非登录式的shell(通常是执行一个脚本),不会加载类似的配置文件,但是会尝试加载$BASH_ENV
这个环境变量所代表的配置文件,如果存在的话。
实践中发现,CentOS会自动生成~/.bash_profile
,Ubuntu会自动生成~/.profile
。两者的作用是类似的,大意是:
- 如果存在
~/.bashrc
,读取这个文件; - 如果存在
~/.local/bin
这个目录,添加到PATH中。具体的措施不太一样,有的会加在PATH的头部,有的则会加在PATH的最后。
因此,在默认情况下,无论是哪一种方式启动,~/.bashrc
中的内容都会被加载执行。
系统通常都会自动生成~/.bashrc
文件,其中的内容却大不相同:
对于CentOS,自动生成的文件中会尝试加载/etc/bashrc
文件
1
2
3
4# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
对于Ubuntu,自动生成的文件头部有如下内容 1
2
3
4
5# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
具体含义是:通过$-
判断当前shell是不是交互式的,如果不是就直接结束,不再执行后面的命令。
上面这个例子说明,不同的系统中这些配置文件发挥的作用是很不一样的。