web-dev-qa-db-ja.com

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.

何か助けてください?

7
user650034

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

クライアントにそれらを送信するように指示する必要があります。たとえばOpenSSHでは、次のようになります。

_ssh -o SendEnv=parameter Host cmd...
_

ただし、サーバーがそれを受け入れることも必要です(OpenSSHでのAcceptEnv構成ディレクティブ)。変数を受け入れることは大きなセキュリティリスクであるため、通常はデフォルトでは行われませんが、一部のsshデプロイメントでは、一部の名前空間で一部の変数を許可します(一部のOpenSSHデプロイメントでは_LC_*_など)。

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

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

上記では、_$parameter_ bashシェル変数の内容を_LC_parameter_環境変数としてsshに渡しています。 sshはそれをsshdに送信します。それが受け入れられた場合は、それを環境変数としてユーザーのログインシェルに渡し、ユーザーのログインシェルがそのcshコマンドに渡します(展開できます)。

ただし、前述のように、Hostマシンの管理者が_AcceptEnv LC_parameter_または_AcceptEnv LC_*_(デフォルトで時々行われる)をsshd構成。

例の_Undefined variable_エラーメッセージは、リモートユーザーのログインシェルがcshまたはtcshであることを示しています。驚きを避けるために、シェルを明示的に呼び出すことをお勧めします(_ssh Host csh_は、ttyが要求されないため、_-T_は必要ないことも意味します)。 _$LC_parameter:q_構文に注意してください。これは、変数の内容を逐語的に渡すcshの方法であり、変数に改行文字が含まれている場合は機能しない_"$LC_parameter"_ではありません。

_LC_*_変数を使用できない場合は、代わりにclientシェル(bash)を使用して変数を展開できます。素朴な方法は

_ssh Host csh << END
echo "$variable"
END
_

ただし、変数の内容がリモートシェルによって解釈されるため、これは危険です。たとえば、_$variable_に_`reboot`_または_"; reboot; : "_が含まれている場合、悪影響が生じる可能性があります。

したがって、最初に、リモートシェルの構文で変数が適切に引用符で囲まれていることを確認する必要があります。ここでは、cshを避け、確実に行うことが難しい場合は、代わりにsh/bash/kshを使用します。

ヘルパー関数を使用して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_の展開がローカルシェルではなくリモートシェルによって行われるようにします。

8

他のトリック(LC_*環境変数を渡すなど)の中で、次のことができます。

PARAMETER="123"
ssh user@Host PARAMETER="$PARAMETER" bash -s <<- __EOF
    echo \$PARAMETER
__EOF

このアプローチの利点は、リモートの構成export PARAMETERLC_に要件がなく、その名前がAcceptEnvに追加されることです(名前が/etc/ssh/sshd_configで始まっていない場合)。ホスト、ローカルホストのSendEnvに追加(-oまたは/etc/ssh/ssh_configに)。

3

4行目のENDSSHから引用符を削除すると、役立つはずです。

礼儀:質問へのコメントの@Archemar。

[〜#〜] warning [〜#〜]この回答へのコメントで@StéphaneChazelasが述べたように、この解決策はhereドキュメントの$parameter変数を展開しますつまり、変数の内容がリモートシェルによってシェルコードとして解釈され、コマンドインジェクションの脆弱性が導入されます。 一般に、そうすることはお勧めしません。

2
ddnomad