将逗号分隔的变量传递给远程 SSH 会话

将逗号分隔的变量传递给远程 SSH 会话

我正在尝试在 shell 脚本中读取逗号分隔的变量并将其拆分,如下所示

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

这是因为heredoc$variable内部的扩展ssh是由本地机器上的本地shell而不是远程shell中扩展的。一般来说,如果我们期望扩展发生在远程 shell 中,我们会转义扩展序列,即变量扩展$varas\$var和命令替换 as\$(..)而不是。$(..)

所以在你的for循环中,分割,发生在你的sed命令中,但是你的"$i"扩展将再次发生在本地 shell 中,而这应该发生在远程 shell 中。由于缺少如果没有适当的转义序列,则echo "$i"永远不会在本地 shell 中看到值。

您可以通过标记为绕过,$i这样\$i它的扩展就会远程发生。此外,循环for i in $(echo $variable | sed sed "s/,/ /g")是一种极其脆弱的方式来迭代 de-limiter 上的列表拆分,read在本例中使用 shell 内置函数

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"

相关内容