Bash and Zsh – Double and Triple Variable Substitution

bashvariable substitutionzsh

Follow-up to the background part in this question.

In bash I can use ${!FOO} for double substitution, in zsh ${(P)FOO}. In both, the old-school (hack-y) eval \$$FOO works.

So, the smartest and most logical thing for me would be ${${FOO}}, ${${${FOO}}}… for double/triple/n substitution. Why doesn’t this work as expected?

Second: What does the \ do in the eval statement? I reckon it’s an escape, making something like eval \$$$FOO impossible. How to do a triple/n substitution with that that works in every shell?

Best Answer

The \ must be used to prevent the expansion of $$ (current process id). For triple substitution, you need double eval, so also more escapes to avoid the unwanted expansions in each eval:

#! /bin/bash
l0=value
l1=l0
l2=l1
l3=l2
l4=l3

echo $l0
eval echo \$$l1
eval eval echo \\$\$$l2
eval eval eval echo \\\\$\\$\$$l3
eval eval eval eval echo \\\\\\\\$\\\\$\\$\$$l4