2

zsh says:

${name}

The value, if any, of the parameter name is substituted.

It then also says:

If a ${...} type parameter expression or a $(...) type command substitution is used in place of name above, it is expanded first and the result is used as if it were the value of name.

My question is why does the following not work then, assuming I am understanding it correctly, i.e. variable names can be nested?

echo $ab $fooz           
foo 123
echo "${${ab}z}"         
zsh: bad substitution
Expected:
123
  • 2
    Simple parameter expressions can not be nested. The resolution is done once from left to right and from top to bottom. – UtLox Jul 28 '19 at 05:50
  • 1
    A zsh question should not be tagged `sh`. `sh` refers to the POSIX specification; zsh does not comply with that spec. (Moreover, the `sh` specification doesn't call for nested parameter expansion to be supported at all). – Charles Duffy Jul 28 '19 at 15:53
  • @Ulox What do you mean top to bottom? – abjoshi - Reinstate Monica Jul 28 '19 at 19:39

1 Answers1

2

What did you expect echo "${${ab}z}" to do? I believe you wanted it to evaluate ${ab} then append a literal z and then interpret the whole thing as if it were a variable name, thus ending up with 123.

Here is your desired outcome with some steps that show us getting there:

$ ab=foo fooz=123
$ echo $ab $fooz
foo 123
$ echo ${(P)ab}

$ echo ${(P)ab}z
z
$ echo ${${(P)ab}z}
123

(Bash can do ${!ab} but can't nest to do the final step. POSIX can't do anything of the sort.)

This uses Zsh's parameter expansion P flag.

Adam Katz
  • 14,455
  • 5
  • 68
  • 83