通過(guò)SSH執(zhí)行遠(yuǎn)程主機(jī)的命令或腳本時(shí),經(jīng)常會(huì)出現(xiàn)找不到自定義環(huán)境變量的問(wèn)題。但是稿辙,如果通過(guò)SSH登錄遠(yuǎn)程主機(jī)授嘀,然后再執(zhí)行相同的命令或腳本,那么此時(shí)執(zhí)行又是成功的诫钓。兩種相似的方法旬昭,得到的結(jié)果卻截然不同,看起來(lái)很詭異的現(xiàn)象菌湃,根本原因在于這兩種方式使用的bash模式不同问拘!
1. 通過(guò)SSH登錄后再執(zhí)行命令和腳本
這種方式會(huì)使用Bash的interactive + login shell模式,這里面有兩個(gè)概念需要解釋:interactive和login。
login故名思義骤坐,即登陸绪杏,login shell是指用戶以非圖形化界面或者以ssh登陸到機(jī)器上時(shí)獲得的第一個(gè)shell,簡(jiǎn)單些說(shuō)就是需要輸入用戶名和密碼的shell纽绍。因此通常不管以何種方式登陸機(jī)器后用戶獲得的第一個(gè)shell就是login shell蕾久。
interactive意為交互式,這也很好理解拌夏,interactive shell會(huì)有一個(gè)輸入提示符僧著,并且它的標(biāo)準(zhǔn)輸入、輸出和錯(cuò)誤輸出都會(huì)顯示在控制臺(tái)上辖佣。所以一般來(lái)說(shuō)只要是需要用戶交互的霹抛,即一個(gè)命令一個(gè)命令的輸入的shell都是interactive shell。而如果無(wú)需用戶交互卷谈,它便是non-interactive shell杯拐。通常來(lái)說(shuō)如bash script.sh此類執(zhí)行腳本的命令就會(huì)啟動(dòng)一個(gè)non-interactive shell,它不需要與用戶進(jìn)行交互世蔗,執(zhí)行完后它便會(huì)退出創(chuàng)建的Shell端逼。
在interactive + login shell模式中,Shell首先會(huì)加載/etc/profile文件污淋,然后再嘗試依次去加載下列三個(gè)配置文件之一顶滩,一旦找到其中一個(gè)便不再接著尋找:
- ~/.bash_profile
- ~/.bash_login
- ~/.profile
2. 通過(guò)SSH直接執(zhí)行遠(yuǎn)程命令和腳本
這種方式會(huì)使用Bash的non-interactive + non-login shell模式,它會(huì)創(chuàng)建一個(gè)shell寸爆,執(zhí)行完腳本之后便退出礁鲁,不再需要與用戶交互。
no-login shell赁豆,顧名思義就是不是在登錄Linux系統(tǒng)時(shí)啟動(dòng)的(比如你在命令行提示符上輸入bash啟動(dòng))仅醇。它不會(huì)去執(zhí)行/etc/profile文件,而會(huì)去用戶的HOME目錄檢查.bashrc并加載魔种。
系統(tǒng)執(zhí)行Shell腳本的時(shí)候析二,就是屬于這種non-interactive shell。Bash通過(guò)BASH_ENV環(huán)境變量來(lái)記錄要加載的文件节预,默認(rèn)情況下這個(gè)環(huán)境變量并沒(méi)有設(shè)置叶摄。如果有指定文件,那么Shell會(huì)先去加載這個(gè)文件里面的內(nèi)容安拟,然后再開始執(zhí)行Shell腳本蛤吓。
3. 結(jié)論
由此可見,如果要解決SSH遠(yuǎn)程執(zhí)行命令時(shí)找不到自定義環(huán)境變量的問(wèn)題去扣,那么可以在登錄用戶的HOME目錄的.bashrc中添加需要的環(huán)境變量柱衔。