${!FOO}
provede dvojitou substituci v bash
, což znamená, že přebírá (řetězcovou) hodnotu FOO a používá ji jako název proměnné.zsh
tuto funkci nepodporuje.
Existuje způsob, jak zajistit, aby to fungovalo stejně v bash
a zsh
?
Pozadí:
Mám seznam proměnných prostředí, jako je
PATH MAIL EDITOR
a chcete nejprve vytisknout názvy proměnných a poté jejich hodnoty.
Toto funguje v bash
ale ne zsh
:
for VAR in LIST
do
echo $VAR
echo ${!VAR}
done
Mělo by to být nějak možné „starým způsobem“ s eval
, ale nemůžu to zprovoznit:
for VAR in LIST
do
echo $VAR
echo `eval $$VAR`
done
Nikdy nepochopím, proč nemohu jednoduše provádět libovolné hluboké substituce jako ${${VAR}}
nebo dokonce ${${${VAR}}}
pokud je to nutné, tak vysvětlení pro to by bylo také hezké.
Přijatá odpověď:
Jak bash, tak zsh mají způsob, jak provádět nepřímou expanzi, ale používají jinou syntaxi.
Provedení nepřímé expanze pomocí eval
je dostatečně snadné; toto funguje ve všech POSIX a většině Bourne shellů. V případě, že hodnota obsahuje znaky, které mají v shellu speciální význam, dbejte na správné uvozování.
eval "value="${$VAR}""
echo "$VAR"
echo "$value"
${${VAR}}
nefunguje, protože to není funkce, kterou implementuje jakýkoli shell. Věc uvnitř složených závorek musí odpovídat pravidlům syntaxe, která nezahrnují ${VAR}
. (V zsh je to podporovaná syntaxe, ale dělá něco jiného:vnořené substituce provádějí postupné transformace na stejné hodnotě; ${${VAR}}
je ekvivalentní $VAR
protože to provede transformaci identity dvakrát na hodnotu.)