profile 与 rc

bash是目前Linux系统中最常见的shell,使用shell时会加载用户配置的环境变量和一些脚本,怎样或以什么样的顺序加载,需要用户在不同的配置文件设置。

一、bash的配置文件

参考 bash 手册,主要配置文件如下:

1. 作为交互式登录shell

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.
当Bash作为交互式登录shell,或者作为非交互式shell使用-login选项被调用时,它首先从文件/etc/profile(如果该文件存在的话)中读取并执行命令,在读取该文件后,它依次查找 ~/.bash_profile、~/.bash_login和~/.profile。然后从第一个存在且可读的文件中读取并执行命令。当启动shell时,可以使用-noprofile选项来抑制这种行为。

When an interactive login shell exits, or a non-interactive login shell executes the exit builtin command, Bash reads and executes commands from the file ~/.bash_logout, if it exists.
当一个交互式登录的shell退出,或者一个非交互式登录的shell执行exit内置命令时,Bash会从~/.bash_logout文件(如果存在的话)中读取并执行命令。

来自bash手册
  • /etc/profile: 最先读取并执行命令的文件
  • ~/.bash_profile: 环境变量可以放在此处
  • ~/.bash_login: 与./profile相同
  • ~/.profile: 主要针对其他shell的兼容
  • ~/.bash_logout: 交互式登录shell退出时执行

实例

# 在 ~/.bash_profile 里写入此句
export TEST='.bash_profile'

# 在 ~/.bash_logout 里写入此句
echo 'bye!'

运行

➜  ~ bash --login
[dmr@dmr-arch ~]$ echo $TEST
.bash_profile
[dmr@dmr-arch ~]$ exit
注销
bye!
➜ ~

2. 作为交互式非登录shell

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.
当一个非登录shell的交互式shell被启动时,如果~/.bashrc文件存在,Bash会从该文件中读取并执行命令。这可以通过使用–norc选项来禁止。–rcfile文件选项将强制Bash从文件而不是~/.bashrc中读取和执行命令。

来自bash手册
  • ~/.bashrc: 直接启动bash时会加载此项文件

3. 作为非交互式shell

When Bash is started non-interactively, to run a shell script, for example, it looks for the variable BASH_ENV in the environment, expands its value if it appears there, and uses the expanded value as the name of a file to read and execute. Bash behaves as if the following command were executed:
当Bash被非交互式地启动时,例如要运行一个shell脚本,它会在环境中寻找变量BASH_ENV,如果它出现在那里,就扩大它的值,并使用扩大后的值作为一个文件的名称来读取和执行。Bash的行为就像执行下面的命令一样:

if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi
来自bash手册

4. 总结

文件名称 交互登录 交互非登录
/etc/profile 直接执行 -
~/.bash_profile 直接执行 -
~/.bash_login 直接执行 -
~/.profile 直接执行 -
~/.bash_logout 退出时执行 -
~/.bashrc 被其他文件执行 直接执行

参考自:关于“.bash_profile”和“.bashrc”区别的总结

二、shell的区别

shell在运行时有两种属性:交互登录

1. 交互

An interactive shell is one started without non-option arguments, unless -s is specified, without specifying the -c option, and whose input and error output are both connected to terminals (as determined by isatty(3)), or one started with the -i option.
交互式shell是指没有非选项参数(脚本文件)的启动,除非指定了-s,没有指定-c选项,其输入和错误输出都连接到终端(由isatty(3)决定),或者用-i选项启动。

An interactive shell generally reads from and writes to a user’s terminal.
交互式shell一般从用户的终端读取和写入。

The -s invocation option may be used to set the positional parameters when an interactive shell is started.
当交互式shell启动时,可以使用-s调用选项来设置位置参数。

来自bash手册

上述启动交互式shell的方法

  • 不带-c参数直接启动
  • -i

辨别方法,判断是否有i标志

[dmr@dmr-arch ~]$ echo $-
himBHs
[dmr@dmr-arch ~]$ bash -c "echo \$-"
hBc
[dmr@dmr-arch ~]$

2. 登录

  • 通过输入密码后启动的shell
  • 使用参数-l|--login启动的shell

辨别方法

➜  ~ bash
[dmr@dmr-arch ~]$ bash -l
[dmr@dmr-arch ~]$ exit
注销
[dmr@dmr-arch ~]$ exit
exit
➜ ~

三、zsh的配置文件

虽然bash很普遍,但zsh相比bash拥有更多可配置的东西,可玩性更高,支持补全、高亮等bash不具备的特性。

  • /etc/zsh/zshenv: 为所有用户设置环境变量
  • ~/.zshenv: 设置指定用户的环境变量
  • /etc/zsh/zprofile: 启动时用于所有用户的命令
  • ~/.zprofile: 启动时用于指定用户的命令
  • /etc/zsh/zshrc: 交互式shell启动时执行
  • ~/.zshrc: 交互式shell启动时执行
  • /etc/zsh/zlogin: 用于在初始进度结束时为所有用户执行命令,将作为登录shell启动时读取
  • ~/.zlogin: 交互式登录shell时执行
  • /etc/zsh/zlogout: 登录shell退出时用于为所有用户执行命令
  • ~/.zlogout: 登录shell退出时用于执行命令

来自:Arch wiki

四、总结

感觉下面这一张图片就够了

shell startup

来自:Shell startup scripts