shell有不同的啟動方式,根據啟動方式的不同會加載不同的配置文件,從而配置不同的環境變量
我們比較常見的啟動方式有:
1.通過linux控制台登錄或者ssh方式,啟動shell,這種情況為登錄式啟動shell
會依次加載/etc/environment, /etc/profile, ~/.bash_profile (或者~/.bash_login 或者 ~/.profile)
而~/.bash_profile中又會加載~/.bashrc,而~/.bashrc又加載 /etc/bashrc , /etc/bashrc又加載 /etc/profile.d/*.sh
2. 通過bash -l 登錄式啟動shell,會加載 /etc/profile, ~/.bash_profile 但不會加載/etc/environment
3,通過bash 非登錄式啟動shell,會加載~/.bashrc,前面說過~/.bashrc腳本又會加載/etc/bashrc , /etc/bashrc又加載 /etc/profile.d/*.sh
可以看出上面的三種方式,不管時登陸時還是非登陸時,都會加載~/.bashrc, /etc/bashrc , /etc/profile.d/*.sh中的內容
而 /etc/profile, ~/.bash_profile只有在登錄式啟動的時候才會加載
如果想給所有的用戶登陸時使用某個環境變量,就在/etc/profile中添加,如果只是給某個用戶登錄時使用某個變量,就在用戶專屬文件 ~/.bash_profile中添加
還有一種啟動方式時定時任務的cron啟動方式
cron啟動方式只會加載/etc/environment,而不會加載/etc/profile或者 /etc/bashrc
在配置文件中輸出配置文件名。測試結果如下
Last login: Fri Feb 7 17:40:49 2020 from 172.25.10.1 //ssh登錄時啟動新進程, /etc/environment*****in /etc/profile //此處能輸出,說明加載了/etc/environment文件 /etc/profile //此處說明加載了 /etc/profile
/etc/profile*****in vagrant/.bash_profile //此處說明加載了 ~/.bash_profile
vagrant/.bash_profile*********in vagrant/.bashrc //此處說明加載了 ~/.bashrc
vagrant/.bashrc*****in /etc/bashrc
/etc/bashrc //此處說明加載了 /etc/bashrc [vagrant@localhost ~]$ sudo su //sudo su命令 廢棄原有的環境變量,並重新加載配置文件,好像開啟了新的進程(但是$$又沒有改變) /etc/environment******in root/.bashrc //此處輸出說明加載了/etc/environment/和~/.bashrc root/.bashrc root/.bashrc*****in /etc/bashrc //此處說明加載了 /etc/bashrc /etc/bashrc [root@localhost vagrant]# bash //bash非登錄式啟動新進程 /etc/bashrc******in root/.bashrc //此處說明加載了~/.bashrc root/.bashrc root/.bashrc*****in /etc/bashrc //此處說明加載了/etc/bashrc /etc/bashrc [root@localhost vagrant]# bash -l //bash登錄式啟動新進程 /etc/bashrc*****in /etc/profile //加載了/etc/profile /etc/profile root/.bash_profile //加載了~/.bash_profile root/.bash_profile******in root/.bashrc root/.bashrc //加載了~/.bashrc root/.bashrc*****in /etc/bashrc //加載了 /etc/bashrc /etc/bashrc [root@localhost vagrant]# (echo a) a
由以上測試可以看出
ssh登錄式進程加載了/etc/environment,/etc/profile,~/.bash_profile(~/.bash_profile內部又加載了~/.bashrc, ~/.bashrc內部又加載了/etc/bashrc ,/etc/bashrc又加載 /etc/profile.d/*.sh)
sudo su切換到root用戶,加載了/etc/environment/和~/.bashrc(其中~/.bashrc內部又加載了/etc/bashrc)
bash命令創建非登錄式新進程加載了 ~/.bashrc(其中~/.bashrc內部又加載了/etc/bashrc)
bash -l命令創建登錄式新進程 加載了/etc/profile,~/.bash_profile(~/.bash_profile內部又加載了~/.bashrc, ~/.bashrc內部又加載了/etc/bashrc, /etc/bashrc又加載 /etc/profile.d/*.sh)
總結:登錄式會加載 /etc/profile,~/.bash_profile ,初期用戶名密碼登錄或者ssh登錄,在加載前面兩個之前,還會加載/etc/environment
非登陸式會加載 ~/.bashrc
sudo命令會清除環境變量並重新加載/etc/environment/和~/.bashrc
不管哪種方式,最終都會加載~/.bashrc, /etc/bashrc, /etc/profile.d/*.sh
cron方式只會加載/etc/environment, 不會加載/etc/profile,也不會加載/etc/bashrc
/etc/environment的加載時機為①ssh登陸時②cron啟動時③sudo su時
在我們寫完定時處理任務的腳本時,
在測試時我們往往式通過在命令行中輸入 bash 腳本文件路徑的方式來執行,而真正的定時處理是通過cron來處理的。
上面已經提到,兩者會加載不同的配置文件。其中命令行bash的方式會加載 ~/.bashrc (~/.bashrc內部又加載了/etc/bashrc, /etc/bashrc又加載 /etc/profile.d/*.sh)
而cron方式只加載了/etc/environment,所以在涉及到使用配置文件的環境變量時,兩者會有差異
那么如何去除這種差異呢?
方式1.最簡單的方式就是直接在/etc/environment中設置環境變量,這樣兩中方式都會取到。命令行bash的方式開啟的新進程,雖然不會重新加載/etc/environment,但是會拷貝父進程的環境變量,而父進程的環境量最初是來自ssh登錄或者sudo su,這兩種方式都會加載/etc/environment。所以使用命令行bash也可以取到/etc/environment中的環境變量
需要注意的是,如果新追加了環境變量,需要重新登錄或者重新sudo su來重新加載/etc/environment,否則命令行bash取不到新追加的環境變量。這是因為在父進程的環境變量中不存在新追加的環境變量
方式2.另一種方式就是在腳本文件中直接通過source(或者 .)的方式引入環境變量所在的文件,這樣不論是命令行bash還是cron方式都會取到環境變量了
如果使用方式2的話,每個腳本文件都需要導入配置文件(當然這也不算麻煩),而方式1並不需要
而方式2的好處是可以自定義將環境變量的文件,並與普通的代碼文件一樣使用git管理。當然也可以寫入/etc/profile這樣的文件中,再導入/etc/profile。不過就無法通過git來管理了
