Por que esta sintaxe não funciona para declarar array associativo

Por que esta sintaxe não funciona para declarar array associativo

Posso usar uma variável dentro da sintaxe ()

#!/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----------

Responder1

Atualmente não é possível (que eu saiba) pegar strings e criar matrizes associativas com elas no Bash. Portanto você deve “avaliá-los” antes de usar a evaldeclaração.

Quando executo seu exemplo, obtenho o seguinte usando o Bash versão 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

Alterar a linha para isso funciona:

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

Executando novamente você agora obtém os resultados esperados:

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

Explicação

Encontrei este SO Q&A intitulado:Bash: Como atribuir um array associativo a outro nome de variável (por exemplo, renomear a variável)?, que ilustra um método para fazer isso, declaremas mostra o quão ilegível esse método realmente é e provavelmente não deve ser usado.

# 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

Este método mostra a $assoc_arrayconversão em uma string e depois a conversão novamente em um array associativo $new_assoc_array. Mas mesmo esse método não pode escapar da necessidade de usar eval. Este é um trecho de código difícil de seguir e mostra por que ele realmente deve ser evitado.

Responder2

Você precisa

eval "b=($a)"

evalavaliará seu argumento como um comando shell após realizar a expansão dos parâmetros. Use com cuidado, no entanto. Certifique-se de que $anão seja definido pela entrada do usuário, pois isso pode causar todos os tipos de problemas.

informação relacionada