How to export an associative array (hash) in bash?

后端 未结 3 1725
梦毁少年i
梦毁少年i 2020-12-16 16:27

Related, but not a duplicate of: How to define hash tables in Bash?

I can define and use a bash hash, but I am unable to export it, even with the -x flag. For examp

相关标签:
3条回答
  • 2020-12-16 16:38

    There isn't really a good way to encode an array variable into the environment. See http://www.mail-archive.com/bug-bash@gnu.org/msg01774.html (Chet Ramey is the maintainer of bash)

    0 讨论(0)
  • This is a bit old but I answer anyway, you could use temp files. If you do it right you can wrapper it to use them like arrays. For example with this function:

    var() { #  set var or add comtent
        case $1 in 
        *=|*=*) 
            local __var_part1=$( echo "$1" | sed -e 's/=.*//' -e 's/[+,-]//' ) # cut +=/=
            local __var_part2=$( echo "$1" | sed -e 's/.*.=//' )
            local __var12=$tmp_dir/$__var_part1
            mkdir -p ${__var12%/*} #create all subdirs if its an array
            case $1 in 
            *+=*)
                    # if its an array try to add new item
                if [ -d $tmp_dir/$__var_part1 ] ; then
                printf  -- $__var_part2 > $tmp_dir/$__var_part1/\  $(( 
                    $( echo $tmp_dir/$__var_part2/* \
                        | tail  | basename )\ + 1 ))
                else
                printf -- "$__var_part2" >> $tmp_dir/$__var_part1  
                fi
                ;;
            *-=*) false ;;
                # else just add content
                *)  printf  -- "$__var_part2" > $tmp_dir/$__var_part1 ;;
            esac
            ;;  
        *) # just print var
            if [ -d $tmp_dir/$1 ] ; then
            ls $tmp_dir/$1
            elif [ -e $tmp_dir/$1 ] ; then 
            cat $tmp_dir/$1
            else
            return 1
            fi
            ;;
        esac    
    }
    
    # you can use mostly like you set vars in bash/shell
    var test='Hello Welt!'
    # if you need arrays set it like this:
    var fruits/0='Apple'
    var fruits/1='Banana'
    
    # or if you need a dict:
    var contacts/1/name="Max"
    var contacts/1/surname="Musterman"
    

    This not the fastest way, but its very flexible, simple and works in nearly all shells.

    0 讨论(0)
  • 2020-12-16 17:02

    As a workaround for this harsh Bash limitation I'm using "serialize to temporary file" method. You can export plain variables, so you can pass an array (associative) through filepath. Of course, this has limitations, but sometimes works and is good enough.

    declare -A MAP # export associative array                                                                           
    MAP[bar]="baz"                                                                        
    declare -x serialized_array=$(mktemp) # create temporary variable 
    # declare -p can be used to dump the definition 
    # of a variable as shell code ready to be interpreted                                       
    declare -p MAP > "${serialized_array}" # serialize an array in temporary file 
    
    # perform cleanup after finishing script                                      
    cleanup() {                                                                   
      rm "${serialized_array}"                                                    
    }                                                                             
    trap cleanup EXIT   
    
    # ... in place where you need this variable ...
    source "${serialized_array}" # deserialize an array                         
    echo "map: ${MAP[@]}" 
    
    0 讨论(0)
提交回复
热议问题