在 Linux 環境,伺服器啟動 / 使用各種 ssh 工具 (e.g. putty) 開啟新的 session 登入時,系統會加載啟動檔案導入環境變量等。本文就是探讨啟動檔案的加載順序。
啟動檔案
有兩種類型的啟動檔案
全局檔案:适用于所有登入伺服器的使用者。一般在
/etc
目錄下。比如:
-
/etc/profiles
-
/etc/bashrc
-
/etc/bash.bashrc
這些,一般都是需要 root 操作權限的。
使用者檔案:适用于某個使用者。一般在使用者自己的根目錄下:
~/
,
/home/username/
。比如:
-
.profiles
-
.bash_profile
-
.bashrc
-
.bash_login
這些,一般使用該使用者賬戶登入即擁有所有操作權限。
以上這些啟動檔案,不一定每個都存在。但是如果存在多個的情況下,加載那個,先後順序,有的時候尤為重要。
Shell 類型
Shell 有三種類型。下面一一介紹。因為不同類型的 Shell ,啟動檔案加載順序不一樣。
Interactive Login Shell
互動式登入 Shell ,比如
ssh
,
putty
xterm
,需要輸一遍使用者名密碼登入的。(有的軟體會存使用者名密碼,第二次登入就不需要輸入了,但也屬于這個類别。)
Interactive non-login Shell
互動式非登入 Shell,當你已經登入了這個 server ,再使用
bash
或者
zsh
開啟一個新的 Shell 視窗,就不需要登入了。
Non-interactive Shell
非互動式 Shell,這個一般指 shell script 腳本,且非以
#!/bin/bash
開頭。
順序
參考網上總結的一張圖,順序如下:
按照 A->B->C 的順序,如果同一類别有多個的話(如B1,B2,B3)就取第一個 available 的。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsISPrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdsATOfd3bkFGazxCMx8VesATMfhHLlN3XnxCMwEzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5CN5YjM1UWZmRDZjBjMhNDOxYzXyEDNwcTM0AzLcFTMxIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLzM3Lc9CX6MHc0RHaiojIsJye.png)
- 總結1:先加載系統檔案,後加載使用者檔案
- 總結2:互動式登入的,一般先看
,再看~/.bash_profile
~/.profile
Why it matters
簡而言之:需要保證各個檔案之間的相容性。
最常見的一個 case , dev 使用 putty 登入上 server 後,即開啟了一個
Interactive Login Shell
。然後跑了一個腳本(以
#!/bin/bash
開頭),即開啟了一個
Interactive non-login Shell
。這時,假設按順序 load 了以下幾個檔案:
-
/etc/profile
-
~/.profile
-
~/.bashrc
需要保證,最後 load 的
~/.bashrc
不會 "無意間地" 把前面定義好的環境變量覆寫掉。
最佳實踐思考
1.不要定義那麼多不同的啟動檔案,盡可能隻使用少量的1-2個檔案,比如
~/.profile
~/.bashrc
。
2.靈活地在腳本中使用
source
3.對于隻适用于 interactive mode 的,可以考慮加上
[ -z "$PS1" ] && return
判斷條件。
參考
- Bash Startup Files Loading Order https://youngstone89.medium.com/unix-introduction-bash-startup-files-loading-order-562543ac12e9
- Understanding Shell Initialization Files and User Profiles in Linux https://www.tecmint.com/understanding-shell-initialization-files-and-user-profiles-linux/
- StackOverFlow Question https://stackoverflow.com/questions/18186929/what-are-the-differences-between-a-login-shell-and-interactive-shell