I want to declare a variable, the name of which comes from the value of another variable, and I wrote the following piece of code:
a="bbb"
$a="ccc"
but it didn't work. What's the right way to get this job done?
I want to declare a variable, the name of which comes from the value of another variable, and I wrote the following piece of code:
a="bbb"
$a="ccc"
but it didn't work. What's the right way to get this job done?
In highly portable shell code, eval is used for this, but if you do it naively, there are going to be nasty escaping issues. This sort of thing is generally safe:
name_of_variable=abc
eval $name_of_variable="simpleword" # abc set to simpleword
This breaks:
eval $name_of_variable="word splitting occurs"
The fix:
eval $name_of_variable="\"word splitting occurs\"" # not anymore
The ultimate fix: put the text you want to assign into a variable. Let's call it safevariable. Then you can do this:
eval $name_of_variable=\$safevariable # note escaped dollar sign
Escaping the dollar sign solves all escape issues. The dollar sign survives verbatim into the eval function, which will effectively perform this:
eval 'abc=$safevariable' # dollar sign now comes to life inside eval!
And of course this assignment is immune to everything. safevariable can contain *, spaces, $, etc. (The caveat being that we're assuming name_of_variable contains nothing but a valid variable name, and one we are free to use: not something special.)
The Korn shell introduces something called namerefs which Bash also implements. With namerefs we can do this directly:
declare -n foo=bar
Now foo is a nameref which holds the name bar. The nameref behaves as a variable. When we assign to foo, we are actually assinging to bar, and $foo produces the value $bar. It's like a symbolic link for variables.
Namerefs provide a much cleaner and safer solution for indirecting on variables than eval at the loss of maximal portability.
$safevariable is the $safe_target_value to assign the variable name saved in $name_of_variable ?eval $name_of_variable="word\ splitting\ occurs" also worksYou can use declare and !, like this:
John="nice guy"
programmer=John
echo ${!programmer} # echos nice guy
Second example:
programmer=Ines
declare $programmer="nice gal"
echo $Ines # echos nice gal
-a-option of declare helps? See declare --help, and test for yourself.${!var_name} form "indirect expansion": gnu.org/software/bash/manual/html_node/…This might work for you:
foo=bar
declare $foo=baz
echo $bar
baz
or this:
foo=bar
read $foo <<<"baz"
echo $bar
baz
declare --help, the -g option to declare always declares a global variable.You could make use of eval for this.
Example:
$ a="bbb"
$ eval $a="ccc"
$ echo $bbb
ccc
Hope this helps!
If you want to get the value of the variable instead of setting it you can do this
var_name1="var_name2"
var_name2=value_you_want
eval temp_var=\$$var_name1
echo "$temp_var"
You can read about it here indirect references.
You can assign a value to a variable using simple assignment using a value from another variable like so:
#!/usr/bin/bash
#variable one
a="one"
echo "Variable a is $a"
#variable two with a's variable
b="$a"
echo "Variable b is $b"
#change a
a="two"
echo "Variable a is $a"
echo "Variable b is $b"
The output of that is this:
Variable a is one
Variable b is one
Variable a is two
Variable b is one
So just be sure to assign it like this b="$a" and you should be good.