${!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.)