SSHで変数を渡す

SSHで変数を渡す

SSH リモートに変数を渡そうとしても機能しません。私のコードは次のとおりです

#!/bin/bash
set -x
conexion="[email protected]"
parameter="$1"
ssh -T $conexion <<'ENDSSH' 
clear
echo "$parameter"
ENDSSH

私は次を実行します:

./script.sh try

それは私に言った:

parameter: Undefined variable.

助けが必要ですか?

答え1

変数(環境変数)渡すことはssh可能ですが、通常は制限されます。

クライアントに送信するように言う必要があります。 OpenSSHを例にすると、次のようになります。

ssh -o SendEnv=parameter host cmd...

ただし、これを受け入れるにはサーバーも必要です(AcceptEnvOpenSSHの設定ディレクティブを使用)。変数を受け入れるとかなりのセキュリティリスクが発生するため、一部のSSH展開では特定の名前空間(LC_*一部のOpenSSH展開など)で特定の変数を許可しますが、通常はデフォルトでは実行されません。

また、を呼び出す前に変数をエクスポートする必要がありますssh。たとえば、次のようになります。

LC_parameter="$parameter" ssh -o SendEnv=LC_parameter host csh << 'END'
echo $LC_parameter:q
END

上記では、シェル変数の内容を環境変数$parameter bashに渡し、これを受け入れると、環境変数としてユーザーのログインシェルに渡してからコマンドに渡します(それから拡張できます)。 )。LC_parametersshsshsshdcsh

hostただし、前述のように、コンピュータ管理者が設定にAcceptEnv LC_parameterまたはを追加しない限りAcceptEnv LC_*(時々デフォルトで実行されます)、この操作は機能しませんsshd

例のエラーメッセージUndefined variableは、リモートユーザーのログインシェルがあることをcsh示しますtcsh。予期しない状況を避けるために、シェルを明示的に呼び出すことをお勧めしssh host cshます-T$LC_parameter:q構文に注意してください。これは、変数に改行文字が含まれている場合に機能しないのとは対照的に、csh変数の内容を文字通り渡す方法です。"$LC_parameter"

変数の使用LC_*がオプションでない場合は、次のものも使用できます。顧客シェル(bashあなたの場合)は変数を拡張します。素朴なアプローチは

ssh host csh << END
echo "$variable"
END

しかし、これは変数の内容がリモートシェルによって解釈されるので危険です。例を$variable含める`reboot`か提示すると、"; reboot; : "悪い結果につながります。

したがって、まずリモートシェルの構文で変数が正しく参照されていることを確認する必要があります。ここではcsh、安定して実行するのが難しい場所を避け、代わりにsh//を使用します。bashksh

sh 参照にヘルパー関数を使用します。

shquote() {
  awk -v q=\' -v b='\\' '
    BEGIN{
      for (i=1; i<ARGC; i++) {
        gsub(q, q b q q, ARGV[i])
       printf "%s ", q ARGV[i] q
      }
      print ""
      exit
    }' "$@"
}

次のように呼び出されますssh

ssh host sh << END
parameter=$(shquote "$parameter")
echo "\$parameter"
END

ローカルシェルではなくリモートシェルで$拡張が行われるように3番目のアイテムをエスケープする方法を見てください。$parameter

答え2

環境変数の転送などの他のトリックに加えて、LC_*次のこともできます。

PARAMETER="123"
ssh user@host PARAMETER="$PARAMETER" bash -s <<- 'EOF'
    echo $PARAMETER
EOF

この方法の利点は、リモートホスト(名前が次に始まらない場合)、ローカルホスト(宛先または宛先)export PARAMETERの設定に名前を追加する必要がないことです。AcceptEnvLC_/etc/ssh/sshd_configSendEnv-o/etc/ssh/ssh_config

答え3

ENDSSH4行目から引用符を削除すると役に立ちます。

提供:質問に対する@Archemarのコメント。

警告するこの回答の説明で@StéphaneChazelasが述べたように、このソリューションを使用すると、ここのドキュメントの変数は$parameterローカルシェルによって拡張されます。つまり、変数の内容はリモートシェルによってシェルコードとして解釈されます。これは、コマンド注入の脆弱性が発生することを意味します。したがって、これは通常推奨されません。

答え4

二重引用符の中に一重引用符を挿入します。

$ file_name="one two"
$ ssh remote ls "'$file_name'"
ls: cannot access 'one two': No such file or directory

一重引用符を削除せずに変数が最初に置き換えられます。このようにして、コンテンツは一重引用符で囲まれ、sshに送信されます。

関連情報