2017-08-29 5 views
1

ショートバージョン: はなぜスクリプトが生成された文字列内のエスケープ文字()埋め込まれた(しかし、見えない)を生成するシェルのでしょうか?シェルスクリプトエスケープダブルクォートでエスケープ文字()を製造する

詳細バージョン:

私はテラフォームコマンドを生成し、それを実行するスクリプトを持っています。コマンド生成は以下のように計算した値を代入する変数を使用することを含む:テラフォームのコマンドを実行すると

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

、私は次のエラーを取得する:

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

私は、変数やエコーでコマンドを置く場合それはバックスラッシュなしで印刷されます。しかし、コピーして端末で手動で実行すると、同じエラーが発生します。二重引用符を削除して手動で入力すると動作します。

+0

はい、ありがとうございました。 – Sami

答えて

1

terraformコマンドに渡す前に、囲み中括弧({および})をエスケープする必要があります。手動で文字をエスケープしないようにするには、printf()の機能をbashに任せて、必要なエスケープシーケンスを実行できます。

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

あなたとして印刷するとき今esc_instances_typesが値を持つことになり、新たな変数に行わエスケープを適用し、terraformコマンド

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

にそれを渡すために-vでコマンドを使用しますこの変数を必要なコマンドに渡すことができます。詳細については、printf() - Format Stringsを参照してください。

関連する問題