Bash應該是我們每天日常工作接觸最多的東西了,就像我們最忠實的朋友,我們有必要了解一下這位朋友的“習性”。
Bash有幾種不同的運行模式,login shell與non-login shell,interactive shell與non-interactive shell(比如執行shell腳本)。這兩種分類方法是交叉的,也就是說一個login shell可能是一個interactive shell,也可能是個non-interactive shell。
在下列情況下,我們可以獲得一個login shell:
- 登錄系統時獲得的頂層shell,無論是通過本地終端登錄,還是通過網絡ssh登錄。這種情況下獲得的login shell是一個交互式shell。
- 在終端下使用--login選項調用bash,可以獲得一個交互式login shell。
- 在腳本中使用--login選項調用bash(比如在shell腳本第一行做如下指定:#!/bin/bash --login),此時得到一個非交互式的login shell。
- 使用"su -"切換到指定用戶時,獲得此用戶的login shell。如果不使用"-",則獲得non-login shell。
login shell與non-login shell的主要區別在於它們啟動時會讀取不同的配置文件,從而導致環境不一樣。login shell啟動時首先讀取/etc/profile全局配置,然后依次查找~/.bash_profile、~/.bash_login、~/.profile三個配置文件,並且讀取第一個找到的並且可讀的文件。login shell退出時讀取並執行~/.bash_logout中的命令。
交互式的non-login shell啟動時讀取~/.bashrc資源文件。非交互式的non-login shell不讀取上述所有配置文件,而是查找環境變量BASH_ENV,讀取並執行BASH_ENV指向的文件中的命令。
如果使用命令"sh"調用bash,bash會盡可能保持向后兼容。作為login shell啟動時,bash依次讀取/etc/profile和~/.profile配置文件。作為non-login shell啟動時,bash讀取環境變量ENV指向的文件。
通常我們要定制一些配置時,將配置寫在~/.bashrc中,然后在~/.bash_profile中讀取~/.bashrc,這樣可以保證login shell和交互式non-login shell得到相同的配置。至於/etc/profile就不要輕易去改啦,畢竟會影響系統全局的配置。
下面做個簡單的實驗來驗證上面的描述。在~/.bash_profile中設置如下變量:
lshell="login shell will see this message"
分別啟動一個交互式non-login shell和交互式login shell,查看lshell變量:
[sw@gentoo ~]$ bash [sw@gentoo ~]$ echo $lshell [sw@gentoo ~]$ exit exit [sw@gentoo ~]$ bash --login [sw@gentoo ~]$ echo $lshell login shell will see this message [sw@gentoo ~]$ exit logout
可見non-login shell並沒有讀取~/.bash_profile,login shell讀取了,與上面的描述相符。
References
1. Linux man page.
