Seguimiento a la parte de fondo en esta pregunta .
En bash
puedo usar ${!FOO}
para doble sustitución, en zsh
${(P)FOO}
. En ambos, la vieja escuela (hack-y) eval \$$FOO
funciona.
Entonces, lo más inteligente y lógico para mí sería la ${${FOO}}, ${${${FOO}}}…
sustitución doble / triple / n. ¿Por qué esto no funciona como se esperaba?
Segundo: ¿Qué hace el \
en la eval
declaración? Creo que es un escape, haciendo que algo sea eval \$$$FOO
imposible. ¿Cómo hacer una sustitución triple / n con la que funciona en cada shell?
bash
zsh
variable-substitution
Profpatsch
fuente
fuente
l3=l2; eval eval eval echo \\\$\\$\$$l3
→53294
así que no es exactamente modular.eval $(eval echo \$$l2)
? Odio bash, no tiene absolutamente ningún sentido.fuente
Supongamos que el valor de
FOO
es un nombre de variable válido (digamosBAR
),eval \$$FOO
divide el valor deBAR
en palabras separadas, trata cada palabra como un patrón comodín y ejecuta la primera palabra del resultado como un comando, pasando las otras palabras como argumentos. La barra invertida frente al dólar hace que sea tratado literalmente, por lo que el argumento pasó aeval
builtin es la cadena de cuatro caracteres$BAR
.${${FOO}}
es un error de sintaxis No hace una "doble sustitución" porque no existe tal característica en ninguno de los shells comunes (de todos modos no con esta sintaxis). En zsh,${${FOO}}
es válido y es una sustitución doble, pero se comporta de manera diferente a lo que desea: realiza dos transformaciones sucesivas en el valor deFOO
, ambas de las cuales son la transformación de identidad, por lo que es solo una forma elegante de escribir${FOO}
.Si desea tratar el valor de una variable como una variable, tenga cuidado de citar las cosas correctamente. Es mucho más fácil si establece el resultado en una variable:
fuente
{ba,z}sh
soluciónAquí hay una función que funciona en ambos
{ba,z}sh
. Creo que también es compatible con POSIX.Sin volverse loco con las citas, puede usarlo para muchos niveles de indirección de la siguiente manera:
O si tiene más (!?!) Niveles de indirección, podría usar un bucle.
Advierte cuando se administra:
fuente
Al igual
${$foo}
que no funciona en lugar de${(P)foo}
inzsh
, tampoco lo hace${${$foo}}
. Solo necesita especificar cada nivel de indirección:Por supuesto,
${!${!foo}}
no funcionabash
porquebash
no permite sustituciones anidadas.fuente
zsh
se instala con mucha más frecuencia de lo que podría suponer. Es posible que no esté vinculado a Mesh
gusta abash
menudo (pero no siempre), pero aún puede estar disponible para los scripts de shell. Piensa en ello como lo haces con Perl o Python.¿Por qué necesitarías hacer eso?
Siempre puedes hacerlo en varios pasos como:
O use una función como:
Luego:
FWIW, en
zsh
:fuente
Solución POSIX
Sin volverse loco con las citas, puede usar esta función para muchos niveles de indirección de la siguiente manera:
O si tiene más (!?!) Niveles de indirección, podría usar un bucle.
Advierte cuando se administra:
fuente