シェルスクリプトからコンマで区切られた変数を読み、次のように分割しようとしています。
while [ -z "$variable" ]
do printf 'variable: '
read -r variable
[ -z "$variable" ] && echo 'Action number cannot be empty; try again.'
done
for i in $(echo ${variable} | sed "s/,/ /g")
do
echo "$i"
done
それが提供する出力は次のとおりです。
abc
def
しかし、SSHで同じ操作を試しても機能しません。次のように試しています。
while [ -z "$variable" ]
do printf 'variable: '
read -r variable
[ -z "$variable" ] && echo 'Action number cannot be empty; try again.'
done
ssh -i my.pem -p 2022 ec2-user@ip-address 'bash -s' << EOF
sudo su - << SUEOF
echo "input $variable"
for i in $(echo ${variable} | sed "s/,/ /g")
do
echo "$i"
done
SUEOF
EOF
ただし、SSHでは入力変数の値は印刷されません。 echoを使用して、変数がSSHセッションに渡されていることを確認し、変数がSSHセッションに渡されていることを確認できます。
variable: abc,def
input abc,def
トラブルシューティングを手伝ってください
ベストアンサー1
$variable
これは、heredoc内の拡張がssh
リモートシェルではなくローカルシステムのローカルシェルによって拡張されるためです。一般的に言えば、リモートシェルで拡張が発生すると予想される場合は、拡張シーケンス、つまり代わりに変数$var
拡張\$var
とコマンド置換をエスケープします\$(..)
。$(..)
したがって、for
ループでは、分割はコマンド,
で発生しますsed
が、"$i"
拡張はリモートシェルで行われる必要があるローカルシェルで再度発生します。なぜなら部族適切なエスケープシーケンスがないと、echo "$i"
ローカルシェルに値が表示されません。
拡張がリモートで発生するようにマークすることで、$i
これをバイパスできます。\$i
また、ループはfor i in $(echo $variable | sed sed "s/,/ /g")
区切り文字でリスト分割を繰り返す非常に脆弱な方法です,
。read
この例では、シェル組み込み関数の使用
ssh -i my.pem -p 2022 ec2-user@ip-address 'bash -s' <<EOF
echo "input $variable"
IFS="," read -ra split <<<"$variable"
for var in "\${split[@]}"; do
printf '%s\n' "\$var"
done
EOF
配列の拡張にエスケープシーケンスを使用し、これらの変数の拡張がローカルシステムではなくリモートで発生することを確認してください"\${split[@]}"
。"\$var"