arraysbashdeclareassociative

declare inside a bash funcion not working as expected with associative arrays


I declare an associative array:

$ declare -A dikv

Initialize it with some key/value pairs:

$ dikv=( ["k1"]="v1" ["k2"]="v2" ["k3"]="v3" ["k4"]="v4")

Then I can save the contents to a file:

$ declare -p dikv > /tmp/dikv.saved

This is the content of /tmp/dikv.saved:

$ cat /tmp/dikv.saved
declare -A dikv=([k4]="v4" [k1]="v1" [k2]="v2" [k3]="v3" )

Now, in a new shell environment, I can load the saved associative array:

$ source /tmp/dikv.saved

And the content is properly accesible:

$ echo "${!dikv[@]}"
k4 k1 k2 k3

$ echo "${dikv[@]}"
v4 v1 v2 v3

This works as expected, nice.

Now I want to do exactly the same but using a bash function:

#! /bin/bash
declare -A dikv
backup_dictionary()
{
    local -n dict_ref=$1
    FILE=$2

    echo "${!dict_ref[@]}"
    echo "${dict_ref[@]}"

    declare -p dict_ref > $FILE
}

dikv=( ["k1"]="v1" ["k2"]="v2" ["k3"]="v3" ["k4"]="v4")
backup_dictionary dikv /tmp/dikv.saved

As you can see, I pass the associative array to the function using local -n. When I run this code, the echo's inside the function print the content of the associative array properly. So, as far as I understand, the associative array has been properly passed as argument.

However, this statement is not working as expected:

$ declare -p dict_ref > $FILE

This is the content of $FILE:

$ cat /tmp/dikv.saved
declare -n dict_ref="dikv"

I expected to see something like this:

dikv=( ["k1"]="v1" ["k2"]="v2" ["k3"]="v3" ["k4"]="v4")

As it happens when not using a bash funcion. Can you explain what happens here? And what should be the proper way to fix this? Thanks!


Solution

  • Your dict_ref stores the string dikv. Hence if you do a declare -p dict_ref, I would expect to see as output something like

    declare -n dict_ref=dikv

    Note that dereferencing (due to the -n declaration) occurs during parameter expansion, i.e. when you do a $dict_ref.

    You could do a

    declare -p "$1" >$FILE