¿Por qué esta sintaxis no funciona para declarar una matriz asociativa?

¿Por qué esta sintaxis no funciona para declarar una matriz asociativa?

¿Puedo usar una variable dentro de la sintaxis ()?

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

Respuesta1

Actualmente no es posible (que yo sepa) poder tomar cadenas y crear matrices asociativas con ellas en Bash. Por lo tanto, debes "evaluarlos" antes de utilizar la evaldeclaración.

Cuando ejecuto su ejemplo obtengo lo siguiente usando la versión 4.1.7 de Bash:

$ ./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

Cambiar la línea a esto funciona:

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

Al volver a ejecutar, obtendrá los resultados esperados:

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

Explicación

Encontré este SO Q&A titulado:Bash: ¿Cómo asignar una matriz asociativa a otro nombre de variable (por ejemplo, cambiar el nombre de la variable)?, que ilustra un método para hacer esto, declarepero muestra cuán ilegible es en realidad este método y probablemente no debería usarse.

# 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 muestra la $assoc_arrayconversión a una cadena y luego la conversión nuevamente a una matriz asociativa $new_assoc_array. Pero ni siquiera este método puede escapar a la necesidad de utilizarlo eval. Este es un fragmento de código difícil de seguir y demuestra por qué realmente debería evitarse.

Respuesta2

Necesitas

eval "b=($a)"

evalevaluará su argumento como un comando de shell después de realizar la expansión de parámetros. Sin embargo, úselo con cuidado. Asegúrese de que $ano esté configurado por entrada del usuario, ya que esto puede provocar todo tipo de problemas.

información relacionada