Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a variable value if variable name is stored as string?

Tags:

string

bash

You can use ${!a}:

var1="this is the real value"
a="var1"
echo "${!a}" # outputs 'this is the real value'

This is an example of indirect parameter expansion:

The basic form of parameter expansion is ${parameter}. The value of parameter is substituted.

If the first character of parameter is an exclamation point (!), it introduces a level of variable indirection. Bash uses the value of the variable formed from the rest of parameter as the name of the variable; this variable is then expanded and that value is used in the rest of the substitution, rather than the value of parameter itself.


X=foo
Y=X
eval "Z=\$$Y"

sets Z to "foo"

Take care using eval since this may allow accidential excution of code through values in ${Y}. This may cause harm through code injection.

For example

Y="\`touch /tmp/eval-is-evil\`"

would create /tmp/eval-is-evil. This could also be some rm -rf /, of course.


For my fellow zsh users, the way to accomplish the same thing as the accepted answer is to use:

echo ${(P)a} # outputs 'this is the real value'

It is appropriately called Parameter name replacement

This forces the value of the parameter name to be interpreted as a further parameter name, whose value will be used where appropriate. Note that flags set with one of the typeset family of commands (in particular case transformations) are not applied to the value of name used in this fashion.

If used with a nested parameter or command substitution, the result of that will be taken as a parameter name in the same way. For example, if you have ‘foo=bar’ and ‘bar=baz’, the strings ${(P)foo}, ${(P)${foo}}, and ${(P)$(echo bar)} will be expanded to ‘baz’.

Likewise, if the reference is itself nested, the expression with the flag is treated as if it were directly replaced by the parameter name. It is an error if this nested substitution produces an array with more than one word. For example, if ‘name=assoc’ where the parameter assoc is an associative array, then ‘${${(P)name}[elt]}’ refers to the element of the associative subscripted ‘elt’.


Modified my search keywords and Got it :).

eval a=\$$a
Thanks for your time.

Had the same issue with arrays, here is how to do it if you're manipulating arrays too :

array_name="ARRAY_NAME"
ARRAY_NAME=("Val0" "Val1" "Val2")

ARRAY=$array_name[@]
echo "ARRAY=${ARRAY}"
ARRAY=("${!ARRAY}")
echo "ARRAY=${ARRAY[@]}"
echo "ARRAY[0]=${ARRAY[0]}"
echo "ARRAY[1]=${ARRAY[1]}"
echo "ARRAY[2]=${ARRAY[2]}"

This will output :

ARRAY=ARRAY_NAME[@]
ARRAY=Val0 Val1 Val2
ARRAY[0]=Val0
ARRAY[1]=Val1
ARRAY[2]=Val2