${!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.
zshno es compatible con esta función.
¿Hay alguna manera de hacer que esto funcione igual en bashy 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 bashpero 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,$VARya 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}shsolució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
functionni[[...]]en POSIXsh.[ "$#" -eq 0 ](o probablemente[ "$#" -ne 1 ]ya que solo espera un argumento).shell-checkpodría ayudar también.${1-}dadaa='"" -o -n 1'[ -z $a ]==0. ¿Pero no$#siempre será una sola ficha?