最新在搭建新的產(chǎn)品環(huán)境就遇到了一個坑睛蛛,使用js 的node-ssh module執(zhí)行遠程機器的sh腳本的時候發(fā)現(xiàn),無法獲取全局的環(huán)境變量撤防。我們知道linux機器的全局環(huán)境變量的設置是在/etc/profile這個文件中的。我在這個文件中添加了JAVA_HOME的環(huán)境變量许溅,并將java的bin目錄添加到了$PATH中,但是通過ssh執(zhí)行遠程腳本的時候拿到的JAVA_HOME的值是空的秉版,但是如果通過xshell工具ssh到遠程主機就可以拿到環(huán)境變量贤重,當時不理解是為什么?后臺通過查了一些資料才了解大致原因沐飘。
原來通過ssh執(zhí)行遠程的命令或者腳本和通過ssh登錄到遠程主機后在執(zhí)行腳本這兩種方式的bash模式不同游桩。bash工作模式主要分為:login + interactive,login + non-interactive 耐朴,non-login + interactive 借卧,non-login + non-interactive 。login 是指需要輸入用戶名和密碼登陸的 shell; interactive 顧名思義為交互式,命令的標準輸入與輸出為該 bash 綁定到的終端筛峭。
* login + interactive
* 登陸 Linux 獲取的第一個 shell
* 通過 ssh user_name @ romote_ip 登陸獲取到的 shell
* 運行命令 bash -l 進入的 shell
* 首先讀取 /etc/profile 文件
* 再從下面三個文件讀取到第一個存在的文件
~/.bash_profile铐刘、~/.bash_login、~/.profile
etc/profile 會依次讀取 /etc/profile.d 下所有文件
* login + non-interactive
* 運行命令 bash -l script.sh
*配置文件讀取同上 該模式比較少用
* non-login + interactive
* 運行命令bash
* 讀取 /etc/bash.bashrc
* 讀取 ~/.bashrc文件
* non-login + non-interactive
* 運行命令 bash script.sh
* 讀取環(huán)境變量 $BASH_ENV 的值,導入該值的配置文件
通過SSH登錄后在執(zhí)行腳本
這種方式使用的是Bash的interactive + login shell模式影晓。
這種模式下回讀取優(yōu)先讀取/etc/profile的配置镰吵,所謂我設置的環(huán)境變量是能夠讀取到的。通過ssh遠程執(zhí)行腳本命令
這個方式使用的是bash的non-login + non-interactive模式挂签。是不會讀取/etc/profile中的配置疤祭,所以我設置的環(huán)境變量是獲取不到的,于是我就去之前已經(jīng)搭建好的機器上查看了$BASH_ENV這個變量的值饵婆,發(fā)現(xiàn)是空的勺馆,這就很奇怪了,為什么這個值是空的ssh遠程執(zhí)行腳本的時候也能成功的拿到JAVA_HOME這個環(huán)境變量呢侨核? 后來發(fā)現(xiàn)是在~/.bashrc中文件中設置的草穆,但是按照上面的工作模式應該是不會讀取這個配置的,于是就又去查了一下資料搓译,從幫助文檔中找到了原因:
Bash attempts to determine when it is being run with its standard input connected to a network connection,
as when executed by the remote shell daemon,
usually rshd, or the secure shell daemon sshd.
If bash determines it is being run in this fashion,
it reads and executes commands from ~/.bashrc,
if that file exists and is read‐ able.
大致的意思就是 bash 會判斷標準輸入是否關聯(lián)到 sshd 這樣的網(wǎng)絡鏈接上,如果是,會讀取 ~/.bashrc 配置文件悲柱。
所以要解決SSH遠程執(zhí)行命令時找不到自定義環(huán)境變量的問題,那么可以在登錄用戶的HOME目錄的.bashrc中添加需要的環(huán)境變量些己。