shell相关-------各环境变量配置文件及对应的shell模式
■各配置文件
1./etc/profile
系统中每个用户登录时都要执行这个脚本,如果系统管理员希望某个设置对所有用户都生效,可以写在这个文件里
2.~/.bash_profile、~/.bash_login和~/.profile
这些是在当前用户主目录下定义的,其实主要是~/.bash_profile,其他两个一般好像不存在。
[root@localhost sabopeusr0]# ls -a ~
. .. .bash_history .bash_logout .bash_profile .bashrc .cshrc .tcshrc anaconda-ks.cfg
~/.bash_profile,如果希望某个设置只对当前用户生效,可以写在这个文件里。
由于这个脚本在/etc/profile之后执行,/etc/profile设置的一些环境变量的值在这个脚本中可以修改,
也就是说,当前用户的设置可以覆盖(Override)系统中全局的设置。
~/.profile这个启动脚本是sh规定的,bash规定首先查找以~/.bash_开头的启动文件,
如果没有则执行~/.profile,是为了和sh保持一致。
3.~/.bash_logout
在退出登录时会执行~/.bash_logout脚本(如果它存在的话)。
4.~/.bashrc
在图形界面下开一个终端窗口,或者在登录Shell提示符下再输入bash命令,就得到一个交互非登录的Shell。
这种Shell在启动时自动执行~/.bashrc文件并以fork子shell的方式执行,即继承父shell的环境变量,并依据.bashrc来修改,
执行完后本地变量不会保存到父shell中去。
[root@localhost sabopeusr0]# ps -ef|grep -v grep|grep bash
sabopeu+ 8906 8905 0 7月26 pts/2 00:00:00 -bash
root 11223 11222 0 09:41 pts/2 00:00:00 bash
[root@localhost sabopeusr0]# bash
[root@localhost sabopeusr0]# ps -ef|grep -v grep|grep bash
sabopeu+ 8906 8905 0 7月26 pts/2 00:00:00 -bash
root 11223 11222 0 09:41 pts/2 00:00:00 bash
root 11392 11223 0 13:00 pts/2 00:00:00 bash
[root@localhost sabopeusr0]#
有时为了使登录Shell也能自动执行~/.bashrc,通常在~/.bash_profile中调用~/.bashrc:
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
上面的意思是,如果~/.bashrc文件存在则source它。多数Linux发行版在创建帐户时会自动创建~/.bash_profile和~/.bashrc脚本,
~/.bash_profile中通常都有上面这几行。所以,如果要在启动脚本中做某些设置,使它在图形终端窗口和字符终端的Shell中都起作用,
最好就是在~/.bashrc中设置。
■Shell模式
1.交互式登录shell启动
/etc/profile,~/.bash_profile,~/.bash_login和~/.profile
1)以Bash的方式启动登录shell(/etc/passwd里定义的shell是/bin/bash,默认就是这种方式)
/etc/profile⇒
~/.bash_profile⇒
~/.profile
(~/.profile这个启动脚本是sh规定的,bash规定首先查找以~/.bash_开头的启动文件,如果没有则执行~/.profile,是为了和sh保持一致。)
2)以sh的方式启动登录shell(/etc/passwd里定义的shell是/bin/sh,默认就是这种方式)
如果以sh
命令启动bash
,bash
将模拟sh
的行为,以~/.bash_
开头的那些启动文件就不认了。
所以,如果作为交互登录Shell启动,或者使用--login参数启动,则依次执行以下文件:
/etc/profile⇒
~/.profile
2.交互式非登录shell启动
~/.bashrc
为什么登录Shell和非登录Shell的启动脚本要区分开呢?
最初的设计是这样考虑的,如果从字符终端或者远程登录,那么登录Shell是该用户的所有其它进程的父进程,也是其它子Shell的父进程,
所以环境变量在登录Shell的启动脚本里设置一次就可以自动带到其它非登录Shell里,
而Shell的本地变量、函数、alias
等设置没有办法带到子Shell里,需要每次启动非登录Shell时设置一遍,
所以就需要有非登录Shell的启动脚本,所以一般来说在~/.bash_profile
里设置环境变量,在~/.bashrc
里设置本地变量、函数、alias
等。
如果你的Linux带有图形系统则不能这样设置,由于从图形界面的窗口管理器登录并不会产生登录Shell,所以环境变量也应该在~/.bashrc
里设置。
3.非交互式启动
为执行脚本而fork出来的子Shell是非交互Shell,启动时执行的脚本文件由环境变量BASH_ENV定义,相当于自动执行以下命令:
if [ -n "$BASH_ENV" ]; then
. "$BASH_ENV";
fi
如果环境变量BASH_ENV的值不是空字符串,则把它的值当作启动文件的文件名,source这个脚本。
通过sh,来fork非交互式shell,则
if [ -n "$ENV" ]; then . "$ENV"; fi
一般来说,如果作为非交互Shell启动,则不执行任何启动脚本。通常我们写的Shell脚本都以#! /bin/sh
开头,都属于这种方式。
简单测试
[sabopeusr0-admin@localhost ~]$ grep tshell .bashrc
tshell="non-login shell will see this message"
export tshell
[sabopeusr0-admin@localhost ~]$ grep lshell .bash_profile
lshell="login shell will see this message"
export lshell
[sabopeusr0-admin@localhost ~]$ bash
[sabopeusr0-admin@localhost ~]$ echo $lshell
[sabopeusr0-admin@localhost ~]$ echo $tshell
non-login shell will see this message
[sabopeusr0-admin@localhost ~]$ exit
exit
[sabopeusr0-admin@localhost ~]$ bash --login
[sabopeusr0-admin@localhost ~]$ echo $lshell
login shell will see this message
[sabopeusr0-admin@localhost ~]$ echo $tshell
non-login shell will see this message
[sabopeusr0-admin@localhost ~]$