How to return an array in bash without using globals?

后端 未结 18 2037
Happy的楠姐
Happy的楠姐 2020-11-29 21:36

I have a function that creates an array and I want to return the array to the caller:

create_array() {
  local my_list=(\"a\", \"b\", \"c\")
  echo \"${my_li         


        
18条回答
  •  长情又很酷
    2020-11-29 22:00

    I tried various implementations, and none preserved arrays that had elements with spaces ... because they all had to use echo.

    # These implementations only work if no array items contain spaces.
    use_array() {  eval echo  '(' \"\${${1}\[\@\]}\" ')';  }
    use_array() {  local _array="${1}[@]"; echo '(' "${!_array}" ')';  }
    

    Solution

    Then I came across Dennis Williamson's answer. I incorporated his method into the following functions so they can a) accept an arbitrary array and b) be used to pass, duplicate and append arrays.

    # Print array definition to use with assignments, for loops, etc.
    #   varname: the name of an array variable.
    use_array() {
        local r=$( declare -p $1 )
        r=${r#declare\ -a\ *=}
        # Strip keys so printed definition will be a simple list (like when using
        # "${array[@]}").  One side effect of having keys in the definition is 
        # that when appending arrays (i.e. `a1+=$( use_array a2 )`), values at
        # matching indices merge instead of pushing all items onto array.
        echo ${r//\[[0-9]\]=}
    }
    # Same as use_array() but preserves keys.
    use_array_assoc() {
        local r=$( declare -p $1 )
        echo ${r#declare\ -a\ *=}
    }  
    

    Then, other functions can return an array using catchable output or indirect arguments.

    # catchable output
    return_array_by_printing() {
        local returnme=( "one" "two" "two and a half" )
        use_array returnme
    }
    eval test1=$( return_array_by_printing )
    
    # indirect argument
    return_array_to_referenced_variable() {
        local returnme=( "one" "two" "two and a half" )
        eval $1=$( use_array returnme )
    }
    return_array_to_referenced_variable test2
    
    # Now both test1 and test2 are arrays with three elements
    

提交回复
热议问题