Acompanhamento da parte de fundo desta pergunta .
Em bash
eu posso usar ${!FOO}
para substituição dupla, em zsh
${(P)FOO}
. Em ambos, a velha escola (hack-y) eval \$$FOO
funciona.
Então, a coisa mais inteligente e lógica para mim seria a ${${FOO}}, ${${${FOO}}}…
substituição dupla / tripla / n. Por que isso não funciona como o esperado?
Segundo: O que \
faz na eval
declaração? Eu acho que é uma fuga, tornando algo como eval \$$$FOO
impossível. Como fazer uma substituição tripla / n pela que funciona em todos os shell?
bash
zsh
variable-substitution
Profpatsch
fonte
fonte
l3=l2; eval eval eval echo \\\$\\$\$$l3
→53294
portanto, não exatamente modular.eval $(eval echo \$$l2)
? Eu odeio bash, não faz absolutamente nenhum sentido.fonte
Supondo que o valor de
FOO
seja um nome de variável válido (digamosBAR
),eval \$$FOO
divida o valor deBAR
em palavras separadas, trate cada palavra como um padrão curinga e execute a primeira palavra do resultado como um comando, passando as outras palavras como argumentos. A barra invertida na frente do dólar faz com que seja tratado literalmente, então o argumento passado para oeval
interno é a cadeia de quatro caracteres$BAR
.${${FOO}}
é um erro de sintaxe. Ele não faz uma "substituição dupla" porque não existe esse recurso em nenhum dos shells comuns (de qualquer maneira, não com esta sintaxe). No zsh,${${FOO}}
é válido e é uma substituição dupla, mas se comporta de maneira diferente do que você gostaria: executa duas transformações sucessivas no valor deFOO
, sendo ambas a transformação de identidade, portanto, é apenas uma maneira elegante de escrever${FOO}
.Se você deseja tratar o valor de uma variável como uma variável, tenha cuidado ao citar as coisas corretamente. É muito mais fácil se você definir o resultado para uma variável:
fonte
{ba,z}sh
soluçãoAqui está uma função que funciona em ambos
{ba,z}sh
. Acredito que também seja compatível com POSIX.Sem enlouquecer com a citação, você pode usá-lo para muitos níveis de indireção, como:
Ou, se você tiver mais (!?!) Níveis de indireção, poderá usar um loop.
Ele avisa quando dado:
fonte
Assim como
${$foo}
não funciona no lugar de${(P)foo}
inzsh
, nem funciona${${$foo}}
. Você só precisa especificar cada nível de indireção:Obviamente,
${!${!foo}}
não funcionabash
, porquebash
não permite substituições aninhadas.fonte
zsh
esteja instalado com muito mais frequência do que você imagina. Pode não estar vinculadosh
comobash
costuma ser (mas nem sempre), mas ainda pode estar disponível para scripts de shell. Pense nisso como você faz Perl ou Python.Por que você precisaria fazer isso?
Você sempre pode fazer isso em várias etapas, como:
Ou use uma função como:
Então:
FWIW, em
zsh
:fonte
Solução POSIX
Sem enlouquecer com a citação, você pode usar esta função para muitos níveis de indireção, como:
Ou, se você tiver mais (!?!) Níveis de indireção, poderá usar um loop.
Ele avisa quando dado:
fonte