# \[BASH - KSH\] Passing array to a function

**URL:** <https://community.unix.com/t/bash-ksh-passing-array-to-a-function/193315>\
**Category:** Shell Programming and Scripting\
**Created:** [April 16, 2008, 10:28am UTC](https://community.unix.com/t/bash-ksh-passing-array-to-a-function/193315 "2008-04-16T10:28:38Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![ripat](https://community.unix.com/letter_avatar/ripat/32/6_449c533f586939b6e5f246632a46421f.png) [@ripat](https://community.unix.com/u/ripat)\
**Post date:** [April 16, 2008, 10:28am UTC](https://community.unix.com/t/bash-ksh-passing-array-to-a-function/193315/1 "2008-04-16T10:28:38Z")

</div>

Passing a array to a function, a basic feature in modern language, seems to be only possible in KSH. Not in BASH. Depite all my efforts I couldn't come to a solution. See the following examples:

It works perfectly in KSH:

```plaintext
#!/usr/bin/ksh

function print_array {
    # assign array by indirect variable reference (namerefs)
    typeset -n array=$1

    # display array content
    echo "${array[*]}"
}

colors=('Pink' 'Light Gray' 'Green')

print_array "colors"

```

But this one gave me headhache:

```plaintext
#!/bin/bash

function print_array {
    # trying to assign array by indirect variable reference
    declare -a array=${!1}
    # local array=${!1} # doesn't work either

    # display array content
    echo "${array[*]}"
}

colors=('Pink' 'Light Gray' 'Green')

print_array "colors"

```

Some reference in the manual for using indirect reference in BASH:

> **[The Linux Documentation Project](https://tldp.org/LDP/abs/html/bashver2.html%5C)**
>
> The Linux Documentation Project is working
> towards developing free, high quality documentation for the Linux operating
> system. The overall goal of the LDP is to collaborate in all of the issues
> of Linux documentation.

---

<div class="post-metadata">

**Author:** ![Perderabo](https://community.unix.com/user_avatar/community.unix.com/perderabo/32/27_2.png) [@Perderabo](https://community.unix.com/u/Perderabo)\
**Post date:** [April 16, 2008, 9:49pm UTC](https://community.unix.com/t/bash-ksh-passing-array-to-a-function/193315/2 "2008-04-16T21:49:15Z")

</div>

This version works with ksh or bash.

```nohighlight
#! /usr/local/bin/bash
#! /usr/bin/ksh

function print_array {
        array_name=$1
        eval echo \${$array_name[*]}
        return
}

colors[0]="Pink"
colors[1]="Light Gray"
colors[2]="Green"

print_array colors
exit 0

```

---

<div class="post-metadata">

**Author:** ![ripat](https://community.unix.com/letter_avatar/ripat/32/6_449c533f586939b6e5f246632a46421f.png) [@ripat](https://community.unix.com/u/ripat)\
**Post date:** [April 17, 2008, 3:21am UTC](https://community.unix.com/t/bash-ksh-passing-array-to-a-function/193315/3 "2008-04-17T03:21:18Z")

</div>

Hi Perderabo,

With my GNU bash, version 3.2.25 it only returns the array name "colors" but not its contents. I have also tried this trick:

```nohighlight
function print_array {
    array_name="$1[*]"
    echo ${!array_name}
}

```

It returns the array elements (on one line) but the local array doesn't exists as such as I can not access it by doing something like:

```nohighlight
function print_array {
    array_name="$1"
    echo ${!array_name[1]}
}

```

This always return the first element "pink" [0]. Of course I could access the array elements by doing:

```nohighlight
function print_array {
    array_name="$1[0]"
    echo ${!array_name}

    array_name="$1[1]"
    echo ${!array_name}

    array_name="$1[2]"
    echo ${!array_name}
}

```

Which is rather inelegant and clumsy. All I wanted is to create a \*local\* copy of the array whose name is passed to the function as positional parameter ($1 $2 ....). By the way, how can I copy an array without looping throught it and assigning values one by one. Of course, the following doesn't work:

```nohighlight
colors=('Pink' 'Light Gray' 'Green')
echo ${colors[@]}

copy_colors=$colors
echo ${copy_colors[@]}

# returns:
# Pink Light Gray Green (3 elements)
# Pink

copy_colors=(${colors[*]})
echo ${copy_colors[*]}
echo ${copy_colors[1]}

# "Light Gray" is split:
# Pink Light Gray Green (4 elements!)
# Light

```

I think I start to understand why members of this forum perfer ksh :=)

---

<div class="post-metadata">

**Author:** ![ripat](https://community.unix.com/letter_avatar/ripat/32/6_449c533f586939b6e5f246632a46421f.png) [@ripat](https://community.unix.com/u/ripat)\
**Post date:** [April 17, 2008, 8:17am UTC](https://community.unix.com/t/bash-ksh-passing-array-to-a-function/193315/4 "2008-04-17T08:17:38Z")

</div>

Boy, this one wasn't easy!

OK, here is what works in bash. Remember, the question was to pass an array to a function and make sure that whatever is done by the function remains local. If the local scope isn't necessary, just remove the "local" declaration.

```nohighlight
#!/bin/bash

function print_array {
    # Setting the shell's Internal Field Separator to null
    OLD_IFS=$IFS
    IFS=''

    # Create a string containing "colors[*]"
    local array_string="$1[*]"

    # assign loc_array value to ${colors[*]} using indirect variable reference
    local loc_array=(${!array_string})

    # Resetting IFS to default
    IFS=$OLD_IFS

    # Checking the second element "Light Gray" (the one with a space)
    echo ${loc_array[1]}
    
}

# create an array and display contents
colors=('Pink' 'Light Gray' 'Green')
echo ${colors[*]}

# call function with positional parameter $1 set to array's name
print_array colors 

# checking whether the function "local" loc_array is visible here
echo "Does the local array exist here? -->${loc_array[*]}<--"
exit 0

```

This returns:

```nohighlight
Pink Light Gray Green
Light Gray
Does the local array exist here? --><--

```

We can also "copy" an array the same way: setting IFS to NULL permit to do variable expansion that preserves the possible spaces in array's elements.

```nohighlight
colors=('Pink' 'Light Gray' 'Green')
OLD_IFS=$IFS
IFS=''
copy_colors=(${colors[*]})
IFS=$OLD_IFS

echo ${copy_colors[*]}
echo ${copy_colors[1]}

```
