7

I'm trying to build an associative array in a function from a list pass in via an arg, but It just isn't working:

#!/usr/bin/env bash



function cwd {
  echo "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
}


function list_commands {
  local root="$1"
  local command_list="${*:2}"
  declare -A cmds
  for cmd in $command_list; do
    cmds["#{$cmd}"]+="$root/scripts/displays/$cmd.sh #{pane_current_path} #{pane_id}"
  done
  echo "$cmds"
}

PLUGIN_ROOT_DIR="$(cwd)"

declare -A cmds=$(list_commands "$PLUGIN_ROOT_DIR" "rbenv_ruby_ver githud")

main "$cmds"

I'm not sure what to do, bash scripting isn't my strong suit (though I'm getting better at it)

what can I do to make this work?

Bear in mind this will be executed in tmux as part of a tpm tmux plugin.

3
  • Command argument lists are flat lists of strings, so there's no "passing" of arrays. Is main something that could see the variable? Is there a textual argument format it would accept and understand? Note that you can't just echo "$cmds" either (try it), so it's already falling over by then anyway. Commented Aug 11, 2018 at 23:57
  • @MichaelHomer, I'm aware of the second point, that's why I'm asking for help, and main, atm is just a function that (should) printout the associative array by iterating over it, but it's not important hence why it's not in the code I posted. Commented Aug 12, 2018 at 0:06
  • It's quite important. Even more so, what are you trying to do with it in the end – what's the final goal? There may be a way to get where you're aiming by a different route if we know what that is. You can edit your question with more details. Commented Aug 12, 2018 at 0:10

1 Answer 1

15

Data structures other than strings can't really be passed around between shell functions. However, you may use name references to pass names of associative arrays (or of whatever other variable you may want). Name references are available in bash since release 4.3.

Example:

foo () {
    declare -n aarr="$1"

    aarr["fookey"]=foovalue
}

declare -A myarray

myarray["mainkey"]=mainvalue
foo myarray

for key in "${!myarray[@]}"; do
    printf '%s = %s\n' "$key" "${myarray[$key]}"
done

Note that bash requires that the name of the name reference variable (aarr above) is not the same as the name of the referenced variable (myarray above).

Testing:

$ bash script.sh
fookey = foovalue
mainkey = mainvalue
2
  • 1
    Thanks, whilst it does require me to declare my aa outside of the function and then pass it in to modify, it dos work and do what I need it to. that and I can't give the reference in the function the same name as the one outside the function Commented Aug 12, 2018 at 8:26
  • @Thermatix You could also use global variables if the function is always going to act on the same variable. With a name reference variable in the function, you get the ability to call it with different associative arrays from elsewhere though. Commented Aug 12, 2018 at 8:33

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.