何`declare -A ASSOCIATIVEARRAY=( $())`仕事?

何`declare -A ASSOCIATIVEARRAY=( $())`仕事?

bash次の式は異議なく評価されます。

declare -A SPANISH=( [rojo]=red [verde]=green [azul]=blue )

...しかし、これはまったく好きではありません。

declare -A SPANISH=( $( echo "[rojo]=red [verde]=green [azul]=blue" ) )
bash: SPANISH: $( echo "[rojo]=red [verde]=green [azul]=blue" ): must use subscript when assigning associative array

いくつかのバリエーションを試しましたが、結果は常に上記のmust use subscript when assigning associative arrayエラーのインスタンスの1つ以上です。

もちろん、この例は愚かです。唯一の目的は、問題を説明することです。初期化する強く打つコマンド置換を使用した連想配列

これは可能ですか?

具体的には、上記の愚かな例を続けると、<COMMAND>そのようなコマンドは何ですか?

declare -A SPANISH=( $( <COMMAND> ) )

...で生成されたのと同じ最終結果を生成します。

declare -A SPANISH=( [rojo]=red [verde]=green [azul]=blue )

以上?

しかし、zshこの状況を処理するのに問題はありません。

$ declare -A SPANISH=( $( echo "rojo red verde green azul blue" ) )
$ echo "${SPANISH[azul]}"
blue

ベストアンサー1

declare -A "SPANISH=($(echo '[rojo]=red [verde]=green [azul]=blue'))"

または:

declare -A "SPANISH=$(echo '([rojo]=red [verde]=green [azul]=blue)')"

または:

declare -A "$(echo 'SPANISH=([rojo]=red [verde]=green [azul]=blue)')"

これに関して、

私のためにbash 5.1を使用します。もちろん、あなたもeval行うことができますが、これが本質的にここで起こっているので、bashは最終的にコマンドの出力をコードとして解釈します。

例えば、

cmd() { echo '[x$(reboot)]=y'; }
declare -A "a=($(cmd))"

reboot次のように実行されます。

eval "
  declare -A a=($(cmd))
"

明示的に使用すると、evalコマンドインジェクションの脆弱性へのパスが存在する場所がより明確になり、将来の混乱を招く設計が修正された場合、将来的に使用される可能性が高まります。

より安全なアプローチのために、cmd出力キーと値をNULで区切って(bash変数にはNULを含めることはできません)、ループに連想配列を埋めることができますが、追加の注意事項としてbashの連想配列には空のキーを持つ要素があります。

fill_assoc() {
  local -n _assoc="$1"
  local _key _value
  while
    IFS= read -rd '' _key &&
    IFS= read -rd '' _value
  do
     _assoc[$_key]=$_value
  done
}
typeset -A assoc
fill_assoc assoc < <(printf '%s\0' rojo red verde green azul blue)

おすすめ記事