关于“.bash_profile”和“.bashrc”区别的总结

bash的startup文件

Linux shell是用户与Linux系统进行交互的媒介,而bash做为目前Linux系统中最经常使用的shell,它支持的startup文件也并不单一,甚至容易让人感到费解。本文以CentOS7系统为例,对bash的startup文件进行一些必要的梳理和总结。shell

根据bash手册上的描述:安全

  • /etc/profile 
    The systemwide initialization file, executed for login shells
  • /etc/bash.bash_logout 
    The systemwide login shell cleanup file, executed when a login shell exits
  • ~/.bash_profile 
    The personal initialization file, executed for login shells
  • ~/.bashrc 
    The individual per-interactive-shell startup file
  • ~/.bash_logout 
    The individual login shell cleanup file, executed when a login shell exits

此外,bash还支持~/.bash_login~/.profile文件,做为对其余shell的兼容,它们与~/.bash_profile文件的做用是相同的。bash

备注:Debian系统会使用~/.profile文件取代~/.bash_profile文件,所以在相关细节上,会与CentOS略有不一样。less

“profile”与“rc”系列

经过名字的不一样,咱们能够直观地将startup文件分为“profile”与“rc”两个系列,其实他们的功能都很相似,可是使用的场景不一样,这也是你们最容易忽略的地方。ide

所谓的不一样场景,其实就是shell的运行模式。咱们知道运行中的bash有“交互”和“登录”两种属性,而执行“profile”系列仍是“rc”系列,就与shell的这两个属性有关。this

关于bash的运行模式,请参见个人另外一篇博客: 
关于“交互式-非交互式”与“登陆-非登录”shell的总结idea

原理上讲,“登录shell”启动时会加载“profile”系列的startup文件,而“交互式非登录shell”启动时会加载“rc”系列的startup文件。spa

“profile”系列的执行场景

根据bash手册上的描述:.net

When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable. The --noprofile option may be used when the shell is started to inhibit this behavior. 
When a login shell exits, bash reads and executes commands from the files ~/.bash_logout and /etc/bash.bash_logout, if the files exists.code

“profile”系列的表明文件为~/.bash_profile,它用于“登陆shell”的环境加载,这个“登陆shell”既能够是“交互式”的,也能够是“非交互式”的。

经过--noprofile选项能够阻止系统加载“profile”系列的startup文件。

交互式登录shell

对于交互式的登录shell而言,CentOS规定了startup文件的加载顺序以下:

登录过程: 
1. 读取并执行/etc/profile文件; 
2. 读取并执行~/.bash_profile文件; 
- 若文件不存在,则读取并执行~/.bash_login文件; 
- 若文件不存在,则读取并执行~/.profile文件;

登出过程: 
1. 读取并执行~/.bash_logout文件; 
2. 读取并执行/etc/bash.bash_logout文件;

为了完成实验,我新建了一些系统默认没有提供的startup文件,例如/etc/bash.bash_logout。而后在每一个文件中打印了文件名,并将它们之间的显式调用语句注释掉,例如~/.bash_profile~/.bashrc的显式调用。

“交互式登录shell”的实验结果以下:

[root@localhost ~]# su - chen Last login: Tue Apr 18 17:15:08 CST 2017 from 192.168.161.1 on pts/2 execute /etc/profile execute ~/.bash_profile -bash-4.2$ exit logout execute ~/.bash_logout execute /etc/bash.bash_logout [root@localhost ~]# 

咱们看到,由于执行了~/.bash_profile文件,因此优先级更低的~/.bash_login~/.profile文件并无被执行。 
咱们能够删除~/.bash_profile~/.bash_login文件,这样系统就会找到并执行~/.profile文件:

[root@localhost ~]# mv /home/chen/.bash_profile /home/chen/.bash_profile.bak [root@localhost ~]# mv /home/chen/.bash_login /home/chen/.bash_login.bak [root@localhost ~]# su - chen Last login: Tue Apr 18 17:27:21 CST 2017 on pts/1 execute /etc/profile execute ~/.profile -bash-4.2$ exit logout execute ~/.bash_logout execute /etc/bash.bash_logout [root@localhost ~]# 

非交互式登录shell

对于非交互式的登录shell而言,CentOS规定了startup文件的加载顺序以下:

登录过程: 
1. 读取并执行/etc/profile文件; 
2. 读取并执行~/.bash_profile文件; 
- 若文件不存在,则读取并执行~/.bash_login文件; 
- 若文件不存在,则读取并执行~/.profile文件;

咱们注意到,与“交互式登录shell”相比,“非交互式登录shell”并无登出的过程,实验也证明了这一点:

-bash-4.2$ bash --login -c "uname -r" execute /etc/profile execute ~/.bash_profile 3.10.0-514.el7.x86_64 -bash-4.2$ # 此时非交互式shell已退出

“rc”系列的执行场景

根据bash手册上的描述:

When an interactive shell that is not a login shell is started, bash reads and executes commands from ~/.bashrc, if that file exists. This may be inhibited by using the --norc option. The --rcfile file option will force bash to read and execute commands from file instead of ~/.bashrc.

“rc”系列的表明文件为~/.bashrc,它用于“交互式非登陆shell”的环境加载。

经过--norc选项能够阻止系统加载“rc”系列的startup文件;经过--rcfile选项可使用指定的文件替代系统默认的~/.bashrc文件。

交互式非登录shell

对于交互式的非登录shell而言,CentOS规定了startup文件的加载顺序以下: 
1. 读取并执行~/.bashrc--rcfile选项指定的文件

这里须要说明,其实“rc”系列startup文件还包括/etc/bashrc。可是系统并不直接调用这个文件,而是经过~/.bashrc文件显式地调用它。

为了完成实验,我在每一个startup文件中打印了文件名,并将它们之间的显式调用语句注释掉,例如~/.bashrc/etc/bashrc的显式调用。

“交互式非登录shell”的实验结果以下:

[root@localhost ~]# su chen execute ~/.bashrc bash-4.2$ exit exit [root@localhost ~]# 

startup文件的默认调用关系

细心的用户会发现,startup文件的加载并不像上面所述的那样简单。这是由于在CentOS中,startup文件之间还存在着默认的显式调用关系,它们是: 
1. ~/.bash_profile显式调用~/.bashrc文件; 
2. ~/.bashrc显式调用/etc/bashrc文件;

再看startup文件

分别打开/etc/profile/etc/bashrc两个文件,咱们能够看到:

[root@localhost ~]# head /etc/profile # /etc/profile # System wide environment and startup programs, for login setup # Functions 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 changes to your environment, as this # will prevent the need for merging in future updates. [root@localhost ~]# head /etc/bashrc # /etc/bashrc # System wide functions and aliases # Environment stuff goes in /etc/profile # 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 changes to your environment, as this # will prevent the need for merging in future updates.

因而可知,“profile”系列文件的主要目的在于为“登陆shell”设置环境变量和启动程序;而“rc”系列文件的主要目的在于设置功能和别名。

顺便提一句,Linux中“rc”是英文“run command”的缩写,表示文件中存放须要执行的命令。其实这也很是符合逻辑,设置功能就要执行shopt命令,而设置别名要执行alias命令。与“rc”系列互补,“profile”系列用来设置环境变量,它不会去调用这两个命令,但却常常须要使用export语句。不信你能够看一看这两个文件。

另外值得一提的是,这两个文件同时提到了一个位置:/etc/profile.d目录。这个目录用于存放个性化配置脚本,你能够把本身须要的全局配置放入以.sh结尾的文件中,系统在执行/etc/profile/etc/bashrc文件时,都会择机调用它们。这样作最大的好处是便于维护,并且相对更加安全。

这些文件的编写方法,能够参考目录下已有的文件:

[root@localhost ~]# ls /etc/profile.d/*.sh /etc/profile.d/256term.sh /etc/profile.d/colorls.sh /etc/profile.d/less.sh /etc/profile.d/colorgrep.sh /etc/profile.d/lang.sh /etc/profile.d/which2.sh

总结

对于“登陆shell”而言,“交互式”执行“登录”和“登出”相关的“profile”系列startup文件,“非交互式”只执行“登录”相关的“profile”系列startup文件;对于“非登录shell”而言,“交互式”执行“rc”系列的startup文件,而“非交互式”执行的配置文件由环境变量BASH_ENV指定。

Linux中startup文件区分全局和我的:全局startup文件放在/etc目录下,用于设置全部用户共同的配置,除非你清楚地知道你在作的事情,不然不要轻易改动它们;我的startup文件放在~目录下,用于设置某个用户的个性化配置。

~/.bash_profile会显式调用~/.bashrc文件,而~/.bashrc又会显式调用/etc/bashrc文件,这是为了让全部交互式界面看起来同样。不管你是从远程登陆(登录shell),仍是从图形界面打开终端(非登录shell),你都拥有相同的提示符,由于环境变量PS1/etc/bashrc文件中被统一设置过。

下面我来对startup文件进行一个完整的总结:

startup文件 交互登录 非交互登录 交互非登录 非交互非登录
/etc/profile 直接执行1 直接执行1 - -
~/.bash_profile 直接执行2 直接执行2 - -
~/.bash_login 条件执行2 条件执行2 - -
~/.profile 条件执行2 条件执行2 - -
~/.bash_logout 直接执行3 不执行 - -
/etc/bash.bash_logout 直接执行4 不执行 - -
~/.bashrc 引用执行2.1 引用执行2.1 直接执行1 -
/etc/bashrc 引用执行2.2 引用执行2.2 引用执行1.1 -

备注: 
1. “直接执行”表示此文件被系统直接调用,它的执行是无条件的; 
2. “条件执行”表示此文件被系统调用是有先决条件的(没有优先级更高的文件可用); 
3. “引用执行”表示此文件不是被系统直接调用的,而是被其余文件显式调用的; 
4. 后面的数字表示文件被调用的顺序,数字越大调用越靠后; 
5. “非交互非登录”shell的配置文件能够由BASH_ENV环境变量指定;

最后我想说的是,知道startup文件什么时候被执行并非关键,关键是要理解本身的状况应该去修改哪一个startup文件。

若是你想对bash的功能进行设置或者是定义一些别名,推荐你修改~/.bashrc文件,这样不管你以何种方式打开shell,你的配置都会生效。而若是你要更改一些环境变量,推荐你修改~/.bash_profile文件,由于考虑到shell的继承特性,这些更改确实只应该被执行一次(而不是屡次)。针对全部用户进行全局设置,推荐你在/etc/profile.d目录下添加以.sh结尾的文件,而不是去修改全局startup文件。

相关文章
相关标签/搜索