web-dev-qa-db-ja.com

引数を使用してssh経由でリモートコマンドを実行する方法は?

.bashrcで、後でコマンドラインで使用できる関数を定義します。

function mycommand() {
    ssh [email protected] cd testdir;./test.sh "$1"
}

このコマンドを使用すると、cdコマンドのみがリモートホストで実行されます。 test.shコマンドはローカルホストで実行されます。これは、セミコロンがsshコマンドとtest.shコマンドの2つの異なるコマンドを分離するためです。

次のように関数を定義してみました(一重引用符に注意してください):

function mycommand() {
    ssh [email protected] 'cd testdir;./test.sh "$1"'
}

cdコマンドとtest.shコマンドを一緒にしようとしましたが、引数$1は、関数に与えるものとは無関係に解決されません。常にコマンドを実行しようとします

./test.sh $1

リモートホスト上。

mycommandを適切に定義するには、スクリプト_test.shがディレクトリtestdirに移動した後にリモートホストで実行され、mycommandに渡された引数をtest.shに渡すことができますか?

52
Alex

代わりに次のようにしてください:

function mycommand {
    ssh [email protected] "cd testdir;./test.sh \"$1\""
}

コマンド全体を単一の文字列として渡す必要がありますが、その単一の文字列では、$1をsshに送信する前に展開する必要があるため、""を使用する必要があります。

更新

これを実際に行う別の適切な方法は、printf %qを使用して引数を適切に引用することです。これにより、スペース、単一引用符、二重引用符、またはシェルにとって特別な意味を持つ可能性のあるその他の文字が含まれている場合でも、引数を安全に解析できます。

function mycommand {
    printf -v __ %q "$1"
    ssh [email protected] "cd testdir;./test.sh $__"
}
  • functionを使用して関数を宣言する場合、()は不要です。
  • あなたがPOSIXistであるという理由だけで、コメントをしないでください。
68
konsolebox

古いスレッドを復活させますが、このかなりきれいなアプローチはリストされていません。

function mycommand() {
    ssh [email protected] <<+
    cd testdir;./test.sh "$1"
+
}
5
Ted Bigham

これは、AWSクラウドで動作する例です。シナリオは、自動スケーリングから起動した一部のマシンが別のサーバーで何らかのアクションを実行し、SSH経由で新しく生成されたインスタンスDNSを渡す必要があることです。

# Get the public DNS of the current machine (AWS specific)
MY_DNS=`curl -s http://169.254.169.254/latest/meta-data/public-hostname`


ssh \
    -o StrictHostKeyChecking=no \
    -i ~/.ssh/id_rsa \
    [email protected] \
<< EOF
cd ~/
echo "Hey I was just SSHed by ${MY_DNS}"
run_other_commands
# Newline is important before final EOF!

EOF
3

私は次を使用して、ローカルコンピューターからリモートでコマンドを実行しています。

ssh -i ~/.ssh/$GIT_PRIVKEY user@$IP "bash -s" < localpath/script.sh $arg1 $arg2
3
muratgozel