2013-03-06 78 views
6

我想在遠程機器上依次執行幾個命令,而後面的一些命令依賴於以前的命令。在一個最簡單的例子,我得到這個:是否可以在遠程ssh命令中使用變量?

ssh my_server "echo this is my_server; abc=2;" 
this is my_server 
abc=2: Command not found. 
ssh my_server "echo this is my_server; abc=2; echo abc is $abc" 
abc: undefined variable 

對於位的背景資料,是我真正想要做的是拼湊的路徑和啓動的Java應用程序:

ssh my_server 'nohup sh -c "((echo this is my_server; jabref_exe=`which jabref`; jabref_dir=`dirname $jabref_exe`; java -jar $jabref_dir/../jabref.jar` $1 &/dev/null) &)"' & 
jabref_dir: Undefined variable. 

這樣,每當jabref被更新到服務器上的新版本時,我就不必手動更新jar文件的路徑。 jabref可執行文件不帶參數,但是用java -jar啓動它,這就是爲什麼我必須稍微調整一下路徑。

目前,我有命令的列表中一個單獨的腳本文件,並調用

ssh my_server 'nohup sh -c "((my_script.sh &/dev/null) &)"' & 

其工作原理,但由於SSH調用已裏面一個腳本文件,它會是不錯的一切融合在一起。

回答

6

從chepner的一些靈感,我現在有一個解決方案,但只有在從bash shell或bash腳本調用時纔有效。它不適用於tcsh。

ssh my_server "bash -c 'echo this is \$HOSTNAME; abc=2; echo abc is \$abc;'" 

在此基礎上,下面的代碼是一個運行的JabRef在遠程服務器上(雖然X-轉發默認和密碼認證用戶無法分辨出它是遠程)本地腳本:

#!/bin/bash 
if [ -f "$1" ] 
then 
    fname_start=$(echo ${1:0:4}) 
    if [ "$fname_start" = "/tmp" ] 
    then 
     scp $1 my_server:$1 
     ssh my_server "bash -c 'source load_module jdk; source load_module jabref; java_exe=\$(which java); jabref_exe=\$(which jabref); jabref_dir=\$(echo \${jabref_exe%/bin/jabref});eval \$(java -jar \$jabref_dir/jabref.jar $1)'" & 
    else 
     echo input argument must be a file in /tmp. 
else 
    echo this function requires 1 argument 
fi 

這是1行腳本load_module,因爲modulecmd設置了環境變量,我無法弄清楚如何在沒有腳本的情況下做到這一點。

eval `/path/to/modulecmd bash load $1`; 

我也看了here文檔,通過How to use SSH to run a shell script on a remote machine?http://tldp.org/LDP/abs/html/here-docs.html啓發。好的部分是它甚至可以從tcsh起作用。我從命令行得到了這個工作,但不是在腳本中。這可能很容易修復,但我現在有一個解決方案,所以我很高興:-)

ssh my_server 'bash -s' << EOF 
echo this is \$HOSTNAME; abc=2; echo abc is \$abc; 
EOF 
6

在這個例子中

ssh my_server "echo this is my_server; abc=2;" 

abc被設置在遠程端,那麼爲什麼不是你的本地計算機上設置應該是清楚的。

在下面的例子中,

ssh my_server "echo this is my_server; abc=2; echo abc is $abc" 

當地殼試圖在論證擴大$abc之前它曾經被髮送到遠程主機。如你預期有輕微的修改將工作:

ssh my_server 'echo this is my_server; abc=2; echo abc is $abc' 

單引號阻止試圖擴大$abc當地的外殼等的文字文本它使遠程主機。


要最終解決您的真正的問題,試試這個:

jabref_dir=$(ssh my_server 'jabref_exe=$(which jabref); jabref_dir=$(dirname $jabref_exe); 
       java -jar $jabref_dir/../jabref.jar > /dev/null; echo $jabref_dir') 

這將在遠程服務器上運行引號的字符串作爲命令,並輸出只有一個字符串:$jabref_dir。該字符串被捕獲並存儲在本地主機上的變量中。

+0

謝謝,這讓我走上正軌。通過引號或'\ $'防止擴展是關鍵。事實證明,服務器上的默認shell是tcsh,這是'abc = 2'不起作用的另一個原因。 – craq 2013-03-11 12:58:56

+0

很棒的回答。我使用Jenkins和SSH Agent插件,它像一個魅力。 – 2017-06-21 16:21:47

相關問題