${!FOO}
realiza una sustitución doble en bash
, lo que significa que toma el valor (cadena) de FOO y lo usa como nombre de variable.zsh
no es compatible con esta función.
¿Hay alguna manera de hacer que esto funcione de la misma manera en bash
? y zsh
?
Antecedentes:
Tengo una lista de variables de entorno, como
PATH MAIL EDITOR
y desea imprimir primero los nombres de las variables y luego sus valores.
Esto funciona en bash
pero no zsh
:
for VAR in LIST
do
echo $VAR
echo ${!VAR}
done
De alguna manera debería ser posible "a la antigua" con eval
, pero no consigo que funcione:
for VAR in LIST
do
echo $VAR
echo `eval $$VAR`
done
Nunca voy a entender por qué no puedo simplemente hacer sustituciones profundas arbitrarias como ${${VAR}}
o incluso ${${${VAR}}}
si es necesario, una explicación para eso también estaría bien.
Respuesta aceptada:
Tanto bash como zsh tienen una forma de realizar la expansión indirecta, pero usan una sintaxis diferente.
Es bastante fácil realizar una expansión indirecta usando eval
; esto funciona en todos los shells POSIX y Bourne. Tenga cuidado de citar correctamente en caso de que el valor contenga caracteres que tengan un significado especial en el shell.
eval "value="${$VAR}""
echo "$VAR"
echo "$value"
${${VAR}}
no funciona porque no es una función que implemente ningún shell. Lo que está dentro de las llaves debe cumplir con las reglas de sintaxis que no incluyen ${VAR}
. (En zsh, esta es una sintaxis admitida, pero hace algo diferente:las sustituciones anidadas realizan transformaciones sucesivas en el mismo valor; ${${VAR}}
es equivalente a $VAR
ya que esto realiza la transformación de identidad dos veces en el valor.)