
¿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 eval
declaració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, declare
pero 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_array
conversió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)"
eval
evaluará 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 $a
no esté configurado por entrada del usuario, ya que esto puede provocar todo tipo de problemas.