2013-03-06 9 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のコールは1つのスクリプトファイル内に既にあるので、一緒にすべてを持っていいだろうどの

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

を呼び出す瞬間

。この例では

答えて

6

chepnerのインスピレーションを受けて、私は今、bashシェルまたはbashスクリプトから呼び出されたときにのみ機能するソリューションを提供します。 tcshでは動作しません。これに基づき

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

、以下のコードは、(デフォルトではX-転送およびパスワードなしの認証で、ユーザは、リモートだ言うことができないが)、リモートサーバー上で実行するローカルJabRefのスクリプトです:

#!/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`; 

は、私はまた、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を拡大しようとしているから、あなたの地元のシェルを防ぎ、そしてそのリテラルテキストは、リモートホストにします。これは、リモートサーバ上でコマンドとして引用符で囲まれた文字列を実行し、出力を正確に1つの文字列ます

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

ありがとう、それは正しい軌道に乗せてくれました。逆のコンマや '\ $ 'による展開を防ぐことが重要でした。サーバ上のデフォルトのシェルがtcshだったことが判明し、それは 'abc = 2'がうまくいかなかったもう一つの理由でした。 – craq

+0

偉大な答え。私はSSH AgentプラグインでJenkinsを使用しています。それは魅力的です。 –

関連する問題