简短版本 为什么shell脚本会在其生成的String中生成转义的字符()嵌入(但不可见)?
详细版本:
我有一个生成 Terraform 命令并执行它的脚本。命令生成涉及使用变量替换计算值,如下所示:
...
AWS_VM_NUMBER=1
types="{"
array_limit=$((AWS_VM_NUMBER - 1))
for ((i = 0; i <= $array_limit; i++));
do
var=AWS_INSTANCE_TYPE_${i+1}
types=${types}"\"$i\"=\"${!var}\","
done
instance_types_array=${types%,}"}"
echo $instance_types_array ## prints {"0"="t2.small"} which is the correct fromat
...
# Now, executing a terraform command like this (please ignore the other variables as they exist else where in the code)
terraform apply -var \'access_key=$AWS_ACCESS_KEY\' \
-var \'secret_key=$AWS_SECRET_KEY\' \
-var \'instance_count=$AWS_VM_NUMBER\' \
-var \'region=$AWS_REGION\' \
-var \'instance_types=$instance_types_array\'
执行terraform命令时,出现以下错误:
无效值“'instance_types = {\”0 \“= \”t2.small \“}'”for flag -var:无法解析变量的值(“{\”0 \“= \”t2.small \}}'“)作为有效的HCL:在1:21:非法字符
如果我将命令放在变量中并回显它,则打印时不带反斜杠。但是,如果我复制它并在终端中手动执行它,我会得到同样的错误。它只有在我删除双引号并手动输入它时才有效!
答案 0 :(得分:1)
在传递给{
命令之前,您还需要转义封闭的双括号(}
和terraform
)。为避免手动转义字符,您可以将其保留在printf()
中bash
的{{1}}函数,它可以执行所需的转义序列。
使用带-v
的命令将转义完成应用于新变量并将其传递给terraform
命令
printf -v esc_instance_types "%q" "${instance_types_array}"
现在esc_instances_types
在打印为
printf "%s\n" "${esc_instances_types}"
\{\"0\"=\"t2.small\"\}
您现在可以将此变量传递给您需要的命令。有关详细信息,请参阅printf() - Format Strings。