Reputation: 77
Is there some way to access a variable by referring to it by a value?
BAR=("hello", "world")
function foo() {
DO SOME MAGIC WITH $1
// Output the value of the array $BAR
}
foo "BAR"
Upvotes: 3
Views: 148
Reputation: 86874
Perhaps what you're looking for is indirect expansion. From man bash
:
If the first character of parameter is an exclamation point (!), a level of variable indirection is introduced. 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. This is known as indirect expansion. The exceptions to this are the expansions of ${!prefix*} and ${!name[@]} described below. The exclamation point must immediately fol‐ low the left brace in order to introduce indirection.
Related docs: Shell parameter expansion (Bash Manual) and Evaluating indirect/reference variables (BashFAQ).
Here's an example.
$ MYVAR="hello world"
$ VARNAME="MYVAR"
$ echo ${!VARNAME}
hello world
Note that indirect expansion for arrays is slightly cumbersome (because ${!name[@]}
means something else. See linked docs above):
$ BAR=("hello" "world")
$ v="BAR[@]"
$ echo ${!v}
hello world
$ v="BAR[0]"
$ echo ${!v}
hello
$ v="BAR[1]"
$ echo ${!v}
world
To put this in context of your question:
BAR=("hello" "world")
function foo() {
ARR="${1}[@]"
echo ${!ARR}
}
foo "BAR" # prints out "hello world"
Indirect expansion of the array syntax will not work in older versions of bash (pre v3). See BashFAQ article.
It appears you cannot use it to retrieve the array size. ARR="#${1}[@]"
will not work. You can however work around this issue by making a copy of the array if it is not prohibitively large. For example:
function foo() {
ORI_ARRNAME="${1}[@]"
local -a ARR=(${!ORI_ARRNAME}) # make a local copy of the array
# you can now use $ARR as the array
echo ${#ARR[@]} # get size
echo ${ARR[1]} # print 2nd element
}
Upvotes: 5
Reputation: 4384
BAR=("hello", "world")
function foo() {
eval echo "\${$1[@]}"
}
foo "BAR"
Upvotes: 2
Reputation: 3139
You can put your arrays into a dictionary matched with their names. Then you can look up this dictionary to find your array and display its contents.
Upvotes: 0