変数をsshリモートに渡そうとしていますが、機能しません。私のコードは:
#!/bin/bash
set -x
conexion="[email protected]"
parameter="$1"
ssh -T $conexion <<'ENDSSH'
clear
echo "$parameter"
ENDSSH
私は実行します:
./script.sh try
それは私に言います:
parameter: Undefined variable.
何か助けてください?
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
_の展開がローカルシェルではなくリモートシェルによって行われるようにします。
他のトリック(LC_*
環境変数を渡すなど)の中で、次のことができます。
PARAMETER="123"
ssh user@Host PARAMETER="$PARAMETER" bash -s <<- __EOF
echo \$PARAMETER
__EOF
このアプローチの利点は、リモートの構成export PARAMETER
のLC_
に要件がなく、その名前がAcceptEnv
に追加されることです(名前が/etc/ssh/sshd_config
で始まっていない場合)。ホスト、ローカルホストのSendEnv
に追加(-o
または/etc/ssh/ssh_config
に)。
4行目のENDSSH
から引用符を削除すると、役立つはずです。
礼儀:質問へのコメントの@Archemar。
[〜#〜] warning [〜#〜]この回答へのコメントで@StéphaneChazelasが述べたように、この解決策はhereドキュメントの$parameter
変数を展開しますつまり、変数の内容がリモートシェルによってシェルコードとして解釈され、コマンドインジェクションの脆弱性が導入されます。 一般に、そうすることはお勧めしません。