1

Fooling around in Bash (just for fun) and discovered that you can reference an array and gets its value from the variable's name:

nick@nick-lt:~$ ARR=(one two);
nick@nick-lt:~$ ARRAYINDIRECT="ARR[@]"
nick@nick-lt:~$ echo "${!ARRAYINDIRECT}"
one two

I was interested if using the same approach we could also get the indexes of the array. Usually, I'd do that by doing:

nick@nick-lt:~$ ARR=(one two); echo "${!ARR[@]}"
0 1

but I can't find a correct syntax to do so. Here's a few ways I tried:

nick@nick-lt:~$ ARR=(one two); ARRAYINDIRECT="ARR[@]"; echo "${!!ARRAYINDIRECT}"
bash: !ARRAYINDIRECT}: event not found

ARR=(one two); ARRAYINDIRECT="!ARR[@]"; echo "${!ARRAYINDIRECT}"
bash: !ARR[@]: event not found

# Increasingly desperate attempts...
nick@nick-lt:~$ ARR=(one two); ARRAYINDIRECT="\!ARR[@]"; echo "${!ARRAYINDIRECT}"

nick@nick-lt:~$ ARR=(one two); ARRAYINDIRECT="ARR[@]"; echo "${!${!ARRAYINDIRECT}}"
bash: ${!${!ARRAYINDIRECT}}: bad substitution
nick@nick-lt:~$ ARR=(one two); ARRAYINDIRECT="ARR[@]"; echo "${\!!ARRAYINDIRECT}"
bash: !ARRAYINDIRECT}: event not found
nick@nick-lt:~$ ARR=(one two); ARRAYINDIRECT="ARR[@]"; echo "${!\!ARRAYINDIRECT}"
bash: ${!\!ARRAYINDIRECT}: bad substitution

Question: is it possible to get the array of indexes of an array after reference by name?

1
  • @wjandrea Yes you can, with anubhava's answer! As stated from the first word in the first line in the first sentence, Fooling around in Bash (just for fun), so doing that wouldn't teach me anything. If you want a valid use case, passing an array to a function by name is something I do to manipulate them (even works on local vars!), so this would be great if I was iterating and mapping the elements of an array to another and I wanted to retain the index structure in the new array. In fact, it'd be great for any index-based manipulation when passed by name. Commented Aug 18, 2016 at 15:56

1 Answer 1

2

If you're using BASH 4.2+ then you can use declare -n:

arr=(one two)

declare -n arrayindirect=arr

echo "${arrayindirect[@]}"
one two

echo "${!arrayindirect[@]}"
0 1

declare -p arrayindirect
declare -n arrayindirect="arr"
Sign up to request clarification or add additional context in comments.

1 Comment

Awesome - much easier to implement than expected too!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.