この構文が連想配列の宣言に機能しないのはなぜですか

この構文が連想配列の宣言に機能しないのはなぜですか

() 構文内で変数を使用できますか

#!/bin/bash
declare -A c
declare -A b
a="[a]=0 [b]=1 [c]=2 [d]=3"
b=($a) # or b=($(echo "$a"))
echo "***********${b[@]}*********"  #********************

c=([a]=0 [b]=1 [c]=2 [d]=3)
echo "---------${c[@]}----------"  #---------0 1 2 3----------

答え1

現時点では、Bash で文字列を取得して連想配列を作成することは (私の知る限り) 不可能です。したがって、ステートメントを使用する前に文字列を「評価」する必要がありますeval

例を実行すると、Bash バージョン 4.1.7 を使用して次の結果が得られます。

$ ./arr.bash 
./arr.bash: line 5: b: [a]=0: must use subscript when assigning associative array
./arr.bash: line 5: b: [b]=1: must use subscript when assigning associative array
./arr.bash: line 5: b: [c]=2: must use subscript when assigning associative array
./arr.bash: line 5: b: [d]=3: must use subscript when assigning associative array

この行を次のように変更すると機能します:

eval "b=($a)" # or b=($(echo "$a"))

再実行すると、期待どおりの結果が得られました。

$ ./arr.bash 
***********0 1 2 3*********
---------0 1 2 3----------

説明

私は次のタイトルの SO Q&A を見つけました:Bash: 連想配列を別の変数名に割り当てる方法 (例: 変数の名前を変更する)?は、これを実行する方法を示していますdeclareが、この方法が実際にはいかに読みにくいかを示しており、おそらく使用すべきではありません。

# declare associative array
declare -A assoc_array=(["key1"]="value1" ["key2"]="value2")
# convert associative array to string
assoc_array_string=$(declare -p assoc_array)
# create new associative array from string
eval "declare -A new_assoc_array="${assoc_array_string#*=}
# show array definition
declare -p new_assoc_array

このメソッドは、 が$assoc_array文字列に変換され、その後連想配列 に戻されることを示しています$new_assoc_array。しかし、このメソッドでも を使用する必要がありますeval。これは理解しにくいコード スニペットであり、なぜこれを避ける必要があるのか​​を示しています。

答え2

必要なのは

eval "b=($a)"

evalは、パラメータ展開を実行した後、その引数をシェル コマンドとして評価します。ただし、注意して使用してください。$aこれは、さまざまな問題を引き起こす可能性があるため、ユーザー入力によって設定されないようにしてください。

関連情報