简体   繁体   中英

Shell script: Pass associative array to another shell script

I want to pass associate array as a single argument to shell script.

mainshellscript.sh:

#!/bin/bash
declare -A cmdOptions=( [branch]=testing [directory]=someDir [function1key]=function1value [function1key]=function1value )
./anothershellscript.sh cmdOptions

anothershellscript.sh:

#!/bin/bash
#--- first approach, didn't work, shows error "declare: : not found"
#opts=$(declare -p "$1")
#declare -A optsArr=${opts#*=}
#---
# second approach, didnt work, output - declare -A optsArr=([0]="" )
#declare -A newArr="${1#*=}"
#declare -p newArr
#---

I'm suspecting that they way I am collecting array in anothershellscript.sh is wrong, I'm finding a way to access map values simply by providing echo "${optsArr[branch]}" shall give testing .

I am using bash version 4.4.23(1)-release (x86_64-pc-msys).

Processes are separate - they do not share variables. A variable set in one process is not visible in the other process. Except: child processes inherit exported variables, but cmdOptions is not exported and you can't export associative arrays anyway.

So pass the string representation of the array to the child, either via arguments or with a file or with an exported variable:

#!/bin/bash
declare -A cmdOptions=( [branch]=testing [directory]=someDir [function1key]=function1value [function1key]=function1value )

export SOME_VAR="$(declare -p cmdOptions)"              # env or
declare -p cmdOptions > some_file.txt                   # file or
./anothershellscript.sh "$(declare -p cmdOptions)"      # arg
# Note - `declare -p` is called _on parent side_!

Then load in the child:

#!/bin/bash
declare -A newArr="${SOME_VAR#*=}"      # env or
. some_file.txt                         # file or
declare -A newArr="${1#*=}"             # arg

# How to load from file so that current environment is not affected:
tmp=$(
   . some_file.txt
   declare -p cmdOptions
)
declare -A newArr=${tmp#*=}" 

Passing Associative array to sub script

Associative arrays and regular arrays are not well exported. But you could pass variables by using declare -p in some wrapper call.

First script:

#!/bin/bash
declare -A cmdOptions=( [branch]=testing     [function1key]=function1value
                        [directory]=someDir  [function2key]=function2value )
declare -a someArray=( foo "bar baz" )

declare -x someVariable="Foo bar baz"    # Using *export* for simple variables

bash -c "$(declare -p cmdOptions someArray);. anothershellscript.sh"

Note syntax . anothershellscript.sh . anothershellscript.sh could be replaced by source anothershellscript.sh .

Doing so, prevent need of temporary files or temporary variable and keep STDIN/STDOUT free.

Then your anothershellscript.sh could use your variables as is.

#!/bin/bash

declare -p cmdOptions someArray someVariable

could work.

You'll have to rebuild that array in second script, here is an example script1:

#!/bin/bash
declare -A test=(
    [v1]=1
    [v2]=2
    [v3]=3
)

for key in "${!test[@]}"; { data+=" $key=${test[$key]}"; }
echo "$data" | ./test2

script2:

#!/bin/bash
read   -ra data
declare -A test2

for item in "${data[@]}"; {
    key="${item%=*}"
    val="${item#*=}"
    test2[$key]="$val"
}
echo "${test2[@]}"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM