Search code examples
arraysbashfunctionvariablescurly-braces

Variable for array name within curly braces (passing or printing an array in bash)


I have a code snippet to print out an array in a shell script:

for i in "${array[@]}"; do
   echo "$i"
   done
}

I wanted to create a function out of it

printArray() {
    for i in "${$1[@]}"; do
      echo "$i"
      done
}

but when I call my function with the array name (which is also available in the shell script), I get an error: ${$1[@]}: bad substitution

What I found out ist that curly braces expand first, probably trying to expand "$1[@]" literally.

I only found answers for numeric expansion like from 1 to 5. So is it possible to replace an array name with a variable inside curly braces?

I expect to be able to put a variable instead of a specific array name in my function.


Solution

  • Here's how I pass and print bash arrays:

    Print a bash array by passing parameters by value

    arrays_join_and_print.sh from my eRCaGuy_hello_world repo:

    Update: even better, see: array_print.sh now, which I just wrote. Sourcing (importing) array_print.sh via . array_print.sh gives you direct access to my two print functions below.

    # Function to print all elements of an array.
    # Example usage, where `my_array` is a bash array:
    #       my_array=()
    #       my_array+=("one")
    #       my_array+=("two")
    #       my_array+=("three")
    #       print_array "${my_array[@]}"
    print_array() {
        for element in "$@"; do
            printf "    %s\n" "$element"
        done
    }
    
    # Usage
    
    # Build an array
    array1=()
    array1+=("one")
    array1+=("two")
    array1+=("three")
    
    # Print it
    echo "array1:"
    print_array "${array1[@]}"
    

    Sample output:

    array1:
        one
        two
        three
    

    Print a bash array by passing the array by reference

    print_array2() {
        # declare a local **reference variable** (hence `-n`) named `array_ref`
        # which is a reference to the first parameter passed in
        local -n array_ref="$1"
    
        for element in "${array_ref[@]}"; do
            printf "    %s\n" "$element"
        done
    }
    
    # Usage
    
    print_array2 "array1"
    # or
    print_array2 array1
    

    Output: same as above.

    Going further:

    For passing arrays as parameters in Bash, I present 3 solutions which can also be used for printing arrays:

    1. [my favorite] Pass arrays by reference (regular arrays and associative bash arrays)
    2. Manually serialize and deserialize arrays
    3. For associative arrays: pass by reference and manually serialize/deserialize