Linux环境变量配置规范

启动流程文件读取顺序

命令行环境(以bash为例)

登录系统时,Shell读取文件的顺序是systemd init --> getty --> 输入账号密码 --> bash login shell --> /etc/profile --> /etc/environment --> $HOME/.bash_profile --> $HOME/.bash_login -->$HOME/.profile
变量从后向前迭代,$HOME/.bash_profile --> $HOME/.bash_login -->$HOME/.profile流程中,只要读到一个就不再读取其他的两个。
交互式启动non-login bash时,不会进行以上步骤,只会读取$HOME/.bashrc,但是指定--login选项时,会执行完整的文件读取流程。
很多其他Shell不遵循以上流程,例如zsh,只会读取/etc/zshrc$HOME/.zshrc

图形界面(Display Manager接管)

使用Display Manager的登录流程截然不同。顺序为systemd init --> display manager --> 输入账号密码 --> /etc/X11/Xsession --> /etc/environment --> $HOME/.xsessionrc
也就是说,图形界面登录自始至终都没有读取Shell的启动文件(/etc/profile$HOME/.profile等等),作为用户,应该创建$HOME/.xsessionrc来配置自定义环境变量。

指导

全局所有用户通用的环境变量,写进/etc/environment,它是由PAM管理的,不是Shell,通用性更好,但是此处不能使用Shell的变量展开,逻辑控制等特性,只能使用变量名=值的格式声明变量。除此之外的一切方法都不推荐,没有其他跨Shell配置环境变量的方法。
用户的Shell设置(别名,函数,选项等等)写入$HOME/.bashrc
如果使用命令行环境,将用户的环境变量写入$HOME/.profile,并创建$HOME/.bash_profile,写入以下内容

1
2
3
if [ -f ~/.profile ]; then
. ~/.profile
fi

如果使用图形环境,创建并修改$HOME/.xsessionrc,写入以下内容

1
2
3
if [ -f ~/.profile ]; then
. ~/.profile
fi

这并非最标准,但是,是最快捷的方法。

其他情况

在命令行界面执行startx

如果通过控制台启动X,那么它会继承login shell的环境变量,而且会再读取一次上面提到过的图形界面的三个文件。

子Shell级联

如果你在login shell中再启动一个non-login shell,如上所述,子Shell不会读取启动流程的文件。为了方便管理,往往会在$HOME/.bash_profile或者$HOME/.profile中写入以下内容以确保两者的一致

1
2
3
4
# set -i意味着Shell是交互的(interactive)
if [ $- == *i* ] && [ -f ~/.bashrc ]; then
. ~/.bashrc
fi

图形化终端模拟器

图形化终端模拟器启动时和non-login shell一样,只会读取$HOME/.bashrc
一些图形化终端模拟器,比如GNOME Terminal,也支持使用login shell启动。

su

在早期版本,su切换用户后会将PATH变量重置为/etc/login.defs中的ENV_PATHENV_SUPATH设置。但是,现在它默认不再修改PATH变量。

环境变量

检查环境变量

使用env命令,或declare -x命令,或export -p命令检查当前的环境变量

最常用的环境变量

1
2
3
4
5
6
7
8
PATH  冒号分隔的命令搜索路径
HOME 用户家目录
LOGNAME 用户名
SHELL 用户使用的Shell
EDITOR 用户使用的编辑器
MAIL 用户的电子邮箱位置
PWD 当前的路径
OLDPWD 上次cd的路径