${!FOO}
realiza una doble sustitución en bash
, lo que significa que toma el valor (cadena) de FOO y lo usa como un nombre de variable.
zsh
no es compatible con esta función.
¿Hay alguna manera de hacer que esto funcione igual 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 bash
pero no en zsh
:
for VAR in LIST
do
echo $VAR
echo ${!VAR}
done
De alguna manera debería ser posible "a la antigua usanza" eval
, pero no puedo hacer 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, por lo que una explicación para eso también sería agradable.
bash
zsh
variable-substitution
for
Profpatsch
fuente
fuente
bash
, de hecho tiene la misma función (y mucho más), solo usa un patrón diferente, a saber${(p)FOO}
.(e)
indicador de expansión de parámetros de zsh se agregó en zsh-2.6-beta17 (mayo de 1996), el(P)
indicador en 3.1.5-pws-7 (1999). bash${!var}
en 2.0 (diciembre de 1996).Respuestas:
Tanto bash como zsh tienen una forma de realizar una expansión indirecta, pero usan una sintaxis diferente.
Es bastante fácil realizar una expansión indirecta usando
eval
; esto funciona en todos los POSIX y la mayoría de los shells Bourne. Tenga cuidado de citar correctamente en caso de que el valor contenga caracteres que tengan un significado especial en el shell.${${VAR}}
no funciona porque no es una característica que implementa ningún shell. La cosa dentro de las llaves debe ajustarse a las reglas de sintaxis que no incluyen${VAR}
. (En zsh, esta es una sintaxis compatible, 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).fuente
El comentario, bajo la pregunta original, de Profpatsch da el ejemplo
${(p)FOO}
para generar el contenido de una referencia de variable indirecta. La bandera es incorrecta o un error tipográfico, debe ser una P mayúscula y no una minúscula p. Uso:${(P)FOO}
.Lo siguiente debería producir el resultado deseado:
Desde la página de manual de zshexpn ; sección - Indicadores de expansión de parámetros :
En un momento leí por qué
${${${VAR}}}
no produce el resultado que esperaba, pero en este momento no puedo encontrarlo. Puedes hacer algo como lo siguiente:fuente
No estás utilizando eval correctamente. En su ejemplo, el valor de $ VAR precedido por un "$" (es decir, `$ VALOR ') se ejecutará como un comando. Eso no es lo que quieres. Desea evaluar la expansión de una variable cuyo nombre se toma de otra variable.
fuente
{ba,z}sh
soluciónAquí hay una función que funciona tanto en {ba, z} sh. Creo que también es compatible con POSIX.
Advierte cuando se administra:
fuente
function
ni[[...]]
en POSIXsh
.[ "$#" -eq 0 ]
(o probablemente[ "$#" -ne 1 ]
ya que solo espera un argumento).shell-check
podría ayudar también.${1-}
dadaa='"" -o -n 1'
[ -z $a ]
==0
. ¿Pero no$#
siempre será una sola ficha?