リモートマシンでいくつかのコマンドを順番に実行したいのですが、後のコマンドのいくつかは前のコマンドに依存しています。最も単純な例では、これを取得します。
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呼び出しはすでに1つのスクリプトファイル内にあるため、すべてをまとめておくと便利です。
Chepnerからのインスピレーションを受けて、bashシェルまたは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
modulecmdは環境変数を設定し、スクリプトを入手せずにそれを行う方法を理解できなかったため、これは1行のスクリプトload_moduleです。
eval `/path/to/modulecmd bash load $1`;
SSHを使用してリモートマシンでシェルスクリプトを実行する方法 および 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
この例では
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
という1つの文字列が出力されます。その文字列はキャプチャされ、ローカルホストの変数に格納されます。