3

So let's say we have:

a=(1 2 3 4)
b=a

I want to get the length of a through b One way could be:

a=(1 2 3 4)
b="a[@]"
c=("${!b}")
echo ${#c[@]}

but i am interested to see if there is a solution without the extra variable

3

For the record, in zsh, where the equivalent of bash's ${!b} is ${(P)b} (and where ${#array[@]} can also be written $#array like in csh)

$ a=(1 2 3 4) b=a
$ echo ${(P)#b}
4

In bash, if you really wanted to use ${!b} indirection, you could always do:

$ a=(1 2 3 4)
$ b='b[(b=${#a[@]}),0]'
$ echo "${!b}"
4

You could use that same kind of trick to have a variable that expands dynamically to the number of elements in $a with:

$ typeset -n b='x[(x=${#a[@]}),0]'
$ echo "$b"
4
$ a+=(more)
$ echo "$b"
5

(here using x instead of b as bash complains if the nameref references itself).

Or you could always use eval:

$ a=(1 2 3 4) b=a
$ eval 'echo "${#'"$b"'[@]}"'
4
1
  • you sir, are a wizard – tturbox Oct 16 '20 at 23:47
3

With indirect variables, that's the way you have to do it.

With namerefs (bash 4.3+), you could do

a=(1 2 3 4)
declare -n b=a
echo "${#b[@]}"

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.