ローカルサーバーからリモートサーバーに変数を渡すには?

ローカルサーバーからリモートサーバーに変数を渡すには?

ローカルサーバー(場所1)からリモートサーバー(場所2)に変数を渡そうとします。このコードの目的は、リモートサーバーの事前定義された場所からファイルをコピーすることです。簡単に言えば、事前定義されたパスを使用してlocation2からlocation1にファイルをコピーしたいと思います。ここで、location1 はローカルサーバーにあり、location2 はリモートサーバーです。コードスニペットを見てください。

$location1=somewhere/on/local_server
$location2=somewhere/on/remote_server

sshpass -p "password" \
  ssh [email protected] 'su -lc "cp -r $location2 $location1";'

私が得るエラーは、$location1と$location2の両方が定義されていないことです。また、場所のパスはいつでも変更される可能性があり、コードの変更が手動で行われると痛みを伴う可能性があるため、手動で入力したくありません。

ベストアンサー1

シェル変数はまさにシェル変数です。クライアントシェルのこの変数は、このsshコマンドまたはリモートホストから起動されたシェルとしてアクセスできません。sshd

出口シェル変数は、実行されたコマンドに環境変数として渡されます。したがって、エクスポートするとlocation1環境変数としてに渡されます。設定ディレクティブ(またはまたは...経由)をssh使用すると、リモートホストに転送しようとします。SendEnv ssh-o~/.ssh/config/etc/ssh/ssh_configsshsshd

ただし、これを機能させるには、この変数を受け取るための設定ディレクティブsshdが必要ですAcceptEnv。しかし、セキュリティ上の理由から、通常はそうではありません。

ただし、多くのデフォルトのssh / sshd展開では、LC_名前が(ローカライズのために)で始まる変数渡しを許可します。したがって、次の利点を享受できます。

LC_location1=$location1 LC_location2=$location2 ssh host 
    'su -lc '\''cp -r -- "$LC_location2" "$LC_location1"'\''

あるいは、ローカルシェル拡張変数をリモートシェルのコマンドラインに渡すこともできます。

ssh host "su -lc 'cp -r -- $location2 $location1'"

ただし、これは以下を実行するのと同じです。

eval eval "cp -r -- $location2 $location1"

つまり、これらの変数は引数として渡されず、シェル(リモートユーザーのログインシェルで始まる)コードcpとして解釈されます(2回)。したがって、変数がある場合、劇的な結果が発生します。shsu$location1/somewhere;rm -rf /

正しい方法は、リモートシェルを正しくエスケープすることです。シェルには2つのレベルがあるため、単一引用符を2回エスケープする必要があります(ksh93ここでは//構文が使用されています)。bashzsh

escaped_location1=\'${location1//\'/\'\\\'\'}\'
escaped_location1=${escaped_location1//\'/\'\\\'\'}
escaped_location2=\'${location2//\'/\'\\\'\'}\'
escaped_location2=${escaped_location2//\'/\'\\\'\'}
ssh host "su -lc 'cp -r -- $escaped_location2 $escaped_location1'"

リモートユーザーのログインシェルはBourneに似ていると仮定します。

おすすめ記事