2

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.

closed as unclear what you're asking by Michael Homer, Jeff Schaller, Thomas, schily, Rui F Ribeiro Aug 12 '18 at 14:02

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 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. – Michael Homer Aug 11 '18 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. – Thermatix Aug 12 '18 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. – Michael Homer Aug 12 '18 at 0:10
3

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
  • 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 – Thermatix Aug 12 '18 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. – Kusalananda Aug 12 '18 at 8:33

Not the answer you're looking for? Browse other questions tagged or ask your own question.