${!FOO}
esegue una doppia sostituzione in bash
, il che significa che prende il valore (stringa) di FOO e lo usa come nome di variabile.zsh
non supporta questa funzione.
C'è un modo per farlo funzionare allo stesso modo in bash
e zsh
?
Sfondo:
Ho un elenco di variabili d'ambiente, come
PATH MAIL EDITOR
e vuoi stampare prima i nomi delle variabili e poi i loro valori.
Funziona in bash
ma non zsh
:
for VAR in LIST
do
echo $VAR
echo ${!VAR}
done
Dovrebbe essere in qualche modo possibile "alla vecchia maniera" con eval
, ma non riesco a farlo funzionare:
for VAR in LIST
do
echo $VAR
echo `eval $$VAR`
done
Non capirò mai perché non posso semplicemente fare sostituzioni profonde arbitrarie come ${${VAR}}
o anche ${${${VAR}}}
se necessario, quindi sarebbe utile anche una spiegazione per questo.
Risposta accettata:
Sia bash che zsh hanno un modo per eseguire l'espansione indiretta, ma usano una sintassi diversa.
È abbastanza facile eseguire l'espansione indiretta utilizzando eval
; questo funziona in tutte le POSIX e nella maggior parte delle shell Bourne. Fai attenzione a citare correttamente nel caso in cui il valore contenga caratteri che hanno un significato speciale nella shell.
eval "value="${$VAR}""
echo "$VAR"
echo "$value"
${${VAR}}
non funziona perché non è una funzionalità implementata da nessuna shell. La cosa all'interno delle parentesi deve essere conforme alle regole di sintassi che non includono ${VAR}
. (In zsh, questa è la sintassi supportata, ma fa qualcosa di diverso:le sostituzioni nidificate eseguono trasformazioni successive sullo stesso valore; ${${VAR}}
è equivalente a $VAR
poiché questo esegue la trasformazione dell'identità due volte sul valore.)