我正在尝试在 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 中,我们会转义扩展序列,即变量扩展$var
as\$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"