0

Without using eval.

this wont work:

astr=(a b c)    
str="#astr[@]"
echo "${!str}"
  • AFAIK, what you are trying to do is impossible. – Wildcard May 6 '16 at 0:08
  • 1
    Why would you not use eval? Note that variable indirection is just as bad as eval in bash if you can't guarantee the content of $str is safe (as in str='a[$(reboot)]') – Stéphane Chazelas Jun 29 '17 at 8:36
2

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
0

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)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.