0

I'm trying to use associative arrays as a work around for Bash's poor function parameter passing. I can declare a global associative array and read/write to that but I would like to have the variable name passed to the function since many times I want to use the same function with different parameter blocks.

Various Stack Overflow posts have approaches for reading a passed array within a function but not writing to it to allow return values. Pseudo Bash for what I'm trying to do is thus:

TestFunc() {
    local __PARMBLOCK__=${1} # Tried ${!1} as well

    # Do something with incoming array

    __PARMBLOCK__[__rc__]+=1 # Error occured
    __PARMBLOCK__[__error__]+="Error in TestFunc"
}

declare -A FUNCPARM

# Populate FUNCPARM
TestFunc FUNCPARM
if [[ ${FUNCPARM[__rc__]} -ne 0 ]]; then
    echo "ERROR : ${FUNCPARM[__error__]}
fi

Is this kind of thing possible or do I really need to abandon Bash for something like Python?

mtnezm
  • 1,009
  • 1
  • 7
  • 19
Jim Hudd
  • 47
  • 10
  • Did you have any problems with [this answer](https://stackoverflow.com/a/55170447/6770384) for the question [How to pass an associative array as argument to a function in Bash?](https://stackoverflow.com/questions/4069188/how-to-pass-an-associative-array-as-argument-to-a-function-in-bash) – Socowi Jun 09 '20 at 08:24

1 Answers1

1

EDIT: Found the duplicate. This is basically the same answer as this one.


You can use a reference variable for that, see help declare:

declare [-aAfFgilnrtux] [-p] [name[=value] ...]
[...]
-n make NAME a reference to the variable named by its value
[...]
When used in a function, declare makes NAMEs local, as with the local command.

f() {
  declare -n paramblock="$1"
  # example for reading (print all keys and entries)
  paste <(printf %s\\n "${!paramblock[@]}") <(printf %s\\n "${paramblock[@]}")
  # example for writing
  paramblock["key 1"]="changed"
  paramblock["new key"]="new output"
}

Example usage:

$ declare -A a=(["key 1"]="input 1" ["key 2"]="input 2")
$ f a
key 2   input 2
key 1   input 1
$ declare -p a
declare -A a=(["key 2"]="input 2" ["key 1"]="changed" ["new key"]="new output" )

This works very well. The only difference to an actual associative array I found so far is, that you cannot print the referenced array using declare -p as that will only show the reference.

Socowi
  • 25,550
  • 3
  • 32
  • 54
  • Perfect! This is exactly what I was looking for. Curiously, in the man page on my Linux system it says "-n" cannot be applied to arrays. I guess that must only refer to non-associative arrays or the manual page is wrong! I don't see the issue of "declare -p" not working being a problem for me. – Jim Hudd Jun 09 '20 at 09:38
  • 1
    @JimHudd At first *"`cannot be applied to arrays`"* stumped me too. However, this means that the reference itself cannot be an array. Still, the referenced variables can be arrays and associative arrays. **Example:** `a=1; b=2; declare -n ref=(a b)` fails. `a=(1 2); declare -n ref=a` works. – Socowi Jun 09 '20 at 09:46