This question already has an answer here:

The following piece of code illustrates my problem I'm afraid I oversimplified it way too much in the first round.

for ii in dog cat
        echo (evaluate $petLover)

I want the code to return the numeric values 1 and 2 rather than dog and cat. Presumably this is easy to do, but I can't seem to see how on the web.

What I really need is a bash equivalent of the "eval" command in matlab

marked as duplicate by Patrick, Anthon, slm, manatwork, rahmu Oct 28 '13 at 14:09

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.


While what StephaneChazelas said is correct in that you can use eval, as a general practice many people try to stay away from eval.

What you can do for this is to use 'indirect expansion'. It's a bashism that is used when you have a variable that contains the name of another variable. To use it, just prefix the variable with a ! inside a curly brace.

For example:

# var=foobar
# varname=var
# echo "${!varname}"

The downside of this is that it's not POSIX. Meaning it's not guaranteed to be available on all shells. But since the tags on your question included bash, this might be acceptable.

  • Thanks Patrick. I like this, but also like the eval approach by @StephaneChazelas. I'm curious as to why people stay away from eval? – Leo Simon Oct 28 '13 at 14:55
  • In most languages eval is considered dirty because there is usually a cleaner way, and it's easy to break/abuse. For example, in this specific case eval will run arbitrary code, when all we want is the 'indirect expansion'. In StephaneChazelas' answer you could exploit it by crafting ii such that the eval would run a command. By doing indirect expansion the expansion would fail, but it would be safe. – Patrick Oct 28 '13 at 16:02
  • ${!x} is bash specific, other shells do it differently when they do support something like that, like zsh has ${(P)x} and ksh93 has namerefs (where ${!x} is actually the opposite of bash's ${!x}) – Stéphane Chazelas Oct 30 '13 at 10:14
  • @StephaneChazelas Yes, that is explained in my answer... – Patrick Oct 30 '13 at 13:58

To dereference, in any Bourne or POSIX shell:

eval "petLover=\${${ii}Lover}"
echo "$petLover"

In the for loop you are not using the text 'dog' and 'cat' not the variables.


for ii in $dog $cat ; do

this will expand to

for ii in 1 2 ; do

Not the answer you're looking for? Browse other questions tagged or ask your own question.