Indirect return of all elements in an array
You need to copy the elements explicitly. For an indexed array:
b=("${a[@]}")
For an associative array (note that a
is the name of the array variable, not a variable whose value is the name of an array variable):
typeset -A b
for k in "${!a[@]}"; do b[$k]=${a[$k]}; done
If you have the variable name in an array, you can use the element-by-element method with an extra step to retrieve the keys.
eval "keys=(\"\${!$name[@]}\")"
for k in "${keys[@]}"; do eval "b[\$k]=\${$name[\$k]}"; done
(Warning, the code in this post was typed directly in a browser and not tested.)
I think the use of indirect reference of bash variable should be treated literally.
Eg. For your original example:
a=(one two three)
echo ${a[*]} # one two three
b=a
echo ${!b[*]} # this would not work, because this notation
# gives the indices of the variable b which
# is a string in this case and could be thought
# as a array that conatins only one element, so
# we get 0 which means the first element
c='a[*]'
echo ${!c} # this will do exactly what you want in the first
# place
For the last real scenario, I believe the code below would do the work.
LIST_lys=(lys1 lys2)
LIST_diaspar=(diaspar1 diaspar2)
whichone=$1 # 'lys' or 'diaspar'
_LIST="LIST_$whichone"[*]
LIST=( "${!_LIST}" ) # Of course for indexed array only
# and not a sparse one
It is better to use notation "${var[@]}"
which avoid messing up with the $IFS
and parameter expansion. Here is the final code.
LIST_lys=(lys1 lys2)
LIST_diaspar=(diaspar1 diaspar2)
whichone=$1 # 'lys' or 'diaspar'
_LIST="LIST_$whichone"[@]
LIST=( "${!_LIST}" ) # Of course for indexed array only
# and not a sparse one
# It is essential to have ${!_LIST} quoted
${!b[*]}
expands to the indices used in array b
.
What you would like has to be done in two steps, so eval
will help: eval echo \${$b[*]}
. (Note the \
which ensures that the first $
will pass the first step, the variable expansion, and will be only expanded in the second step by eval
.)
According to Parameter Expansion !
is both used for indirect expansion ({!a}
), Names matching prefix (${!a*}
) and List of array keys (${!a[*]}
). Because List of array keys has the same syntax as your intended indirect expansion+array element expansion, the later is not supported as is.