15

I need to indirectly reference a variable in the bash shell.

I basically want to what you can do in make by writing $($(var)).

I have tried using ${$var} which would be the most straight forward solution in bash but then I get this error:

bash: ${$var}: bad substitution

Is there a way to do this?

What I am trying to do is to iterate over all the arguments ($1, $2, $3, ...) to a program using an iteration variable and I cannot do this without indirection.

3 Answers 3

16

If you have var1=foo and foo=bar, you can get bar by saying ${!var1}. However, if you want to iterate over the positional parameters, it's almost certainly better to do

for i in "$@"; do
    # something
done
3
  • Is there a way to add multiple levels of indirection?
    – wefwefa3
    Commented Sep 17, 2015 at 12:44
  • 1
    Not that I can quickly find. The obvious guess of ${!!var1} doesn't work. However, you can always do it manually, e.g. tmp=${!var1}; echo ${!tmp}.
    – Tom Hunt
    Commented Sep 17, 2015 at 15:05
  • 1
    You don't even need to write in "$@". Just for i; do #something; done is enough.
    – user000001
    Commented Mar 6, 2022 at 7:05
8

Using /bin/bash:

foo=bar
test=foo
echo ${!test}

# prints -> bar
1
  • 1
    This also worked for me in an Alpine sh (ash).
    – b01
    Commented May 16 at 21:23
1

Using grep + awk

foo=bar
var_name=foo
set | grep -v var_name | grep ^"${var_name}=" | awk -F= '{ print $2 }'

the output will be

bar

To prove that this approach works, check the bash script:

#!/bin/bash

function show_variable_value() {
  name=$1
  value=$(set | grep -v name | grep ^"${name}="  | awk -F= '{ print $2 }' )
  echo "${value}"
}


foo='bar'

# getting the variable value indirectly from the variable name
value=$(show_variable_value foo)
if [ "${value}" == "${foo}" ]; then
  echo "The function returned indirectly the variable value from the variable name >>> '${value}' == '${foo}'"
else
  echo "This approach does not work"
fi

6
  • Doesn't that still expand the variable directly in the second grep? Commented Mar 1, 2022 at 17:25
  • It was a typo on the second grep, it was missing a $ character => grep $test. Please, upvote instead because it's working as you can see in the bash script above. Commented Mar 3, 2022 at 23:50
  • Can you perhaps add more explanation to this answer? I think you are dumping environment with set, grepping away the line starting with the outer variable name, then grepping for the content of that variable, presumably to pull out the name it references and outputting it. However, wouldn't the value of test be bar since you set it to $foo? Commented Mar 4, 2022 at 19:45
  • The function show_variable_value() is getting the first argument as the variable name and as you explained, it's not presumably, it really gets the value of the variable indirectly (using the variable name), the value of the test variable will be => "bar". Please, try to execute the script, play a bit with the script setting different values to the variable foo and you will see it works perfectly fine. Commented Mar 6, 2022 at 6:31
  • I made an adjustment in the first section, it had one extra $ and instead of getting the variable name was getting the variable value. Instead of test, to be more cohesive I am using var_name. Commented Mar 6, 2022 at 6:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .