Without using eval.
this wont work:
astr=(a b c)
str="#astr[@]"
echo "${!str}"
Without using eval.
this wont work:
astr=(a b c)
str="#astr[@]"
echo "${!str}"
From a tip here, I managed to do this:
astr=(a b c)
declare -n astrRef="astr"
echo ${#astrRef[@]}
This allows also to create such array or simply assign values thru indirection:
declare -n astrRef="astr"
astrRef=(d e f)
declare -p astrRef astr
astrRef+=(g)
declare -p astrRef astr
What about this, which works at least on bash 3.x and above:
astr=(a b c)
str=astr[@] # Our reference to an array
local arr=("${!str}") # Copy into an array using indirect ref
echo ${#arr[*]}
# 3
bstr=("a foo" "a bar" "a fox" "a buzz")
str=bstr[@]
local arr=("${!str}")
echo ${#arr[*]}
# 4
We use local keyword to keep our working variable arr local to the function, but this is optional. In fact because of the limitation of bash, arr can be used also to access the elements in the (indirect) array, like:
echo ${arr[1]} # Print 2nd element
echo ${#arr[1]} # ... print its size
(Tested on bash 3.1.23, bash 4.3.48 and 4.4.12)