Linux系統中有時會遇到一些登陸初始化故障,會阻止用戶進入系統(比如ETX無法打開桌面)或者導致某些工具運行失敗(LSF bsub任務是無法完成初始化),所以瞭解Linux系統用戶登錄時的環境加載順序,對debug和解決如上問題是很有幫助的。
一、交互式登陸shell的環境加載順序
交互式,指的是指通過終端輸入命令並獲得執行結果;登陸,指的是指需要用戶名、密碼登錄後才能進入;shell,即我們常用的bash/tcsh等shell環境。這是最常見的一種使用模式。
下面,我們以linux系統默認的bash shell爲例,求證一下登陸shell時候的環境加載順序,涉及到的系統/用戶環境配置文件有如下幾種:
/etc/profile: 用於系統環境設置/系統路徑設置/通用系統配置/定義系統級別的行爲,這些配置都是對全局用戶生效的。
/etc/profile.d/*: 用於定義系統/應用的啓動腳本,和/etc/profile相比,好處是可以和分散化和模塊化配置,具有更好的可擴展性。
~/.bash_profile: 用於用戶環境定製/定義用戶別名/設置特定命令的行爲/個性化提示符/配置用戶特定的應用程序設置。
~/.bash_login: 同上,作爲~/.bash_profile的補充。
~/.profile: 同上。
~/.bashrc: 同上。
當用戶通過用戶名、密碼進入交互式shell的時候,加載配置文件的順序如下:
/etc/profile -> /etc/profile.d/* -> ~/.bash_profile -> ~/.bash_login(前者不存在時) -> ~/.profile(前者不存在時) -> ~/.bashrc(被前序腳本觸發)
驗證如下:
在相關配置文件中插入一些echo語句,打印指定信息。
[root@ic-monitor01 ~]# grep ">>>" /etc/profile /etc/profile.d/* ~/.bash_profile ~/.bash_login ~/.profile ~/.bashrc /etc/profile:echo ">>> /etc/profile" /etc/profile.d/test.sh:echo ">>> /etc/profile.d/test.sh" /root/.bash_profile:echo ">>> ~/.bash_profile" /root/.bash_login:echo ">>> ~/.bash_login" /root/.profile:echo ">>> ~/.profile" /root/.bashrc:echo ">>> ~/.bashrc"
採用ssh的方式登錄一個交互式shell。
[root@ic-monitor01 ~]# ssh root@ic-monitor01 Password: Last login: Sun Apr 7 15:22:00 2024 from fe80::e42:a1ff:fe1c:4dae%ens192 >>> /etc/profile >>> /etc/profile.d/test.sh >>> ~/.bash_profile >>> ~/.bashrc
此種情況下,登陸順序是 /etc/profile -> /etc/profile.d/* -> ~/.bash_profile -> ~/.bashrc(被前序腳本觸發)
因爲~/.bash_profile存在,所以~/.bash_login和~/.profile並沒有被執行。
去掉~/.bash_profile再試。
[root@ic-monitor01 ~]# rm -rf ~/.bash_profile [root@ic-monitor01 ~]# ssh root@ic-monitor01 Password: Last login: Sun Apr 7 17:46:12 2024 from fe80::e42:a1ff:fe1c:4dae%ens192 >>> /etc/profile >>> /etc/profile.d/test.sh >>> ~/.bash_login -bash-4.2#
~/.bash_profile被移除後,~/.bash_login確實按照順位直接被執行了。
但是也注意到~/.bashrc沒有被執行就直接進入shell環境了,這是因爲執行~/.bashrc是~/.bash_profile中定義的行爲,~/.bash_profile被移除後,~/.bashrc也就沒有地方會觸發執行了。
去掉~/.bash_login再試。
[root@ic-monitor01 ~]# ssh root@ic-monitor01 Password: Last login: Sun Apr 7 17:53:29 2024 from fe80::e42:a1ff:fe1c:4dae%ens192 >>> /etc/profile >>> /etc/profile.d/test.sh >>> ~/.profile -bash-4.2#
~/.bash_profile和~/.bash_login被移除後,~/.profile確實按照順位直接被執行了。
二、交互式非登陸shell的環境加載順序
交互式非登錄shell,指的是不需要用戶名和密碼即可打開的shell,比如在shell中直接執行“bash”來打開一個新的子shell。
當進入交互式非登錄shell的時候,加載配置文件的順序如下:
/etc/profile -> /etc/profile.d/*
驗證如下:
[root@ic-monitor01 ~]# bash >>> ~/.bashrc >>> /etc/profile.d/test.sh
我們可以看到,它只重新加載了系統配置文件,用戶配置文件並沒有被重複加載,但是相關的變量設置已經直接被當前shell所繼承。
三、一些環境配置的注意事項
* 系統配置,尤其是~/.bashrc這個最常用的用戶配置文件,需要儘量保持乾淨,以防止一些系統變量設置衝突導致的shell環境無法進入。下面是一些常見的衝突項示例:
- 設置PS1變量,會導致ETX新開terminal無法進入shell環境。
- 直接設置anaconda的bin路徑到PATH,會導致debus配置衝突,引起shell初始化失敗。
* 分類別的全局系統/程序配置,在/etc/profile.d中以獨立腳本的形式創建,比如module files的profile.sh配置文件,就可以copy/link到這個目錄,作爲全局的modules配置,這樣更容易管理。