0

I have the following setup:

#! /bin/bash

init_globals() {
    declare -gA global_arr1=( ["key"]="val" )
}
init_globals

echo "${global_arr1["key"]}" # WORKS! print val

local_arr1=( ["key"]="local val" )
i=1
temp=local_arr$i
current_arr=${!temp}
echo ${current_arr["key"]} # WORKS! print local val

temp=global_arr$i
current_arr=${!temp}
echo ${current_arr["key"]} # DOESN'T WORK! expect val but print nothing...

I'm trying to access globally defined associative array, based on the variable i. So I use indirect expansion to assign current_arr to what I want. It works perfectly for an associative array defined locally. But it doesn't work with global array. Why so?

Boyang
  • 2,520
  • 5
  • 31
  • 49
  • This is the point where you are probably better off switching to a language with proper data structure support. Regular arrays have a purpose in shells (passing lists of whitespace-containing values as distinct arguments) aside from trying to build data structures. Associative arrays, on the other hand, seem like a very limited substitute for real, first-class container data structures. – chepner Feb 09 '16 at 17:57
  • @chepner Haha, I totally agree. My company and co-workers don't. They love bash too much. – Boyang Feb 09 '16 at 18:02

2 Answers2

3

You didn't declare local_arr1 as an associative array. It springs into existence with

local_arr1=( [key]="local val" )

so bash creates a normal array for you, with key understood as a variable whose value is the index in the array (zero in this case, as there's no $key). You can test it with set -eu or key=1.

Note that the correct way to use indirection on arrays is to include the index in the string:

arr1[2]=x
i=1
j=2
tmp=arr$i[$j]
echo ${!tmp}
choroba
  • 231,213
  • 25
  • 204
  • 289
1

It is because:

local_arr1=( ["key"]="local val" )

is not really an associative array. You can check by:

declare -p local_arr1

which prints:

declare -a local_arr1='([0]="local val")'

If you use it right:

declare -A local_arr1=( ["key"]="local val" )

then behavior will be same for both arrays.

anubhava
  • 761,203
  • 64
  • 569
  • 643