解決SSH遠程執行命令找不到環境變量的問題

經過SSH執行遠程主機的命令或腳本時,常常會出現找不到自定義環境變量的問題。可是,若是經過SSH登陸遠程主機,而後再執行相同的命令或腳本,那麼此時執行又是成功的。兩種類似的方法,獲得的結果卻大相徑庭,看起來很詭異的現象,根本緣由在於這兩種方式使用的bash模式不一樣!shell

1. 經過SSH登陸後再執行命令和腳本

這種方式會使用Bash的interactive + login shell模式,這裏面有兩個概念須要解釋:interactive和login。bash

login故名思義,即登錄,login shell是指用戶以非圖形化界面或者以ssh登錄到機器上時得到的第一個shell,簡單些說就是須要輸入用戶名和密碼的shell。所以一般無論以何種方式登錄機器後用戶得到的第一個shell就是login shell。app

interactive意爲交互式,這也很好理解,interactive shell會有一個輸入提示符,而且它的標準輸入、輸出和錯誤輸出都會顯示在控制檯上。因此通常來講只要是須要用戶交互的,即一個命令一個命令的輸入的shell都是interactive shell。而若是無需用戶交互,它即是non-interactive shell。一般來講如bash script.sh此類執行腳本的命令就會啓動一個non-interactive shell,它不須要與用戶進行交互,執行完後它便會退出建立的Shell。ssh

在interactive + login shell模式中,Shell首先會加載/etc/profile文件,而後再嘗試依次去加載下列三個配置文件之一,一旦找到其中一個便再也不接着尋找:ui

  • ~/.bash_profile
  • ~/.bash_login
  • ~/.profile

2. 經過SSH直接執行遠程命令和腳本

這種方式會使用Bash的non-interactive + non-login shell模式,它會建立一個shell,執行完腳本以後便退出,再也不須要與用戶交互。spa

no-login shell,顧名思義就是否是在登陸Linux系統時啓動的(好比你在命令行提示符上輸入bash啓動)。它不會去執行/etc/profile文件,而會去用戶的HOME目錄檢查.bashrc並加載。命令行

系統執行Shell腳本的時候,就是屬於這種non-interactive shell。Bash經過BASH_ENV環境變量來記錄要加載的文件,默認狀況下這個環境變量並無設置。若是有指定文件,那麼Shell會先去加載這個文件裏面的內容,而後再開始執行Shell腳本。code

3. 結論

因而可知,若是要解決SSH遠程執行命令時找不到自定義環境變量的問題,那麼能夠在登陸用戶的HOME目錄的.bashrc中添加須要的環境變量。server

四、示例

當登陸以後,直接在某臺遠程主機:10.0.63.9上執行日期格式化的命令時,打印的是正確的,以下:blog

[root@dev-appserver2 ~]# buildTimeStamp=2017-09-27T16:58:47.291+08:00; buildTimeStampStr=$(date -d $buildTimeStamp "+%y%m%d%H%M%S"); echo $buildTimeStampStr
170927165847

當在另一臺主機(10.0.251.216)上遠程執行ssh命令時,打印的結果不正確(差了八個時區),以下:

[root@host-10-0-251-216 ~]# cat sshtime
buildTimeStamp=2017-09-27T16:58:47.291+08:00; buildTimeStampStr=$(date -d $buildTimeStamp "+%y%m%d%H%M%S"); echo $buildTimeStampStr

[root@host-10-0-251-216 ~]# a=`cat sshtime `
[root@host-10-0-251-216 ~]# echo $a
buildTimeStamp=2017-09-27T16:58:47.291+08:00; buildTimeStampStr=$(date -d $buildTimeStamp "+%y%m%d%H%M%S"); echo $buildTimeStampStr
[root@host-10-0-251-216 ~]# ssh root@10.0.63.9 $a
root@10.0.63.9's password:
170927085847

此時修改10.0.63.9上,root根目錄下的.bashrc文件,增長TZ的設置,再次執行ssh打印的結果是正確的:

[root@dev-appserver2 ~]# cat .bashrc
# .bashrc
 
# User specific aliases and functions
 
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
 
export TZ="Asia/Shanghai"
 
# Source global definitions
if [ -f /etc/bashrc ]; then
    . /etc/bashrc
fi
[root@dev-appserver2 ~]#
[root@host-10-0-251-216 ~]# ssh root@10.0.63.9 $a
root@10.0.63.9's password:
170927165847
相關文章
相關標籤/搜索