Shell script producing the escaping character (\) with escaped double qoutes

1.2k Views Asked by At

Short version: why would shell script produce the escaping character () embedded (but not visible) in its produced String?

Detailed version:

I have a script which generates a Terraform command and executes it. The command generation involves using variables to substitute computed values as below:

...
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\' 

When the terraform command is executed, I get the following error:

invalid value "'instance_types={\"0\"=\"t2.small\"}'" for flag -var: Cannot parse value for variable ("{\"0\"=\"t2.small\"}'") as valid HCL: At 1:21: illegal char

If I put the command in a variable and echo it, it prints without the backslash. However, if I copy it and execute it manually in terminal, I get the same error. It will only work if I delete the double quotes and type them back manually!

1

There are 1 best solutions below

0
On BEST ANSWER

You need to escape the enclosing double-braces({ and }) also before passing to the terraform command. To avoid escaping the characters manually you can leave it to printf() function in bash which can do the required escape sequences.

Use the command with -v to apply the escaping done to a new variable and pass that to the terraform command

printf -v esc_instance_types "%q" "${instance_types_array}"

Now the esc_instances_types will have a value when printed as

printf "%s\n" "${esc_instances_types}"
\{\"0\"=\"t2.small\"\}

You can now pass this variable to the command you need. See printf() - Format Strings for more information.