How to pass an array as function argument?

Struggling for a while passing an array as argument but it's not working anyway. I've tried like below:

#! /bin/bash

function copyFiles{
   arr="$1"
   for i in "${arr[@]}";
      do
          echo "$i"
      done

}

array=("one" "two" "three")

copyFiles $array

An answer with explanation would be nice.

Edit: Basically, i will eventually call the function from another script file. Plz explain the constraints if possible.


Solution 1:

  • Expanding an array without an index only gives the first element, use

    copyFiles "${array[@]}"
    

    instead of

    copyFiles $array
    
  • Use a she-bang

    #!/bin/bash
    
  • Use the correct function syntax

    Valid variants are

    function copyFiles {…}
    function copyFiles(){…}
    function copyFiles() {…}
    

    instead of

    function copyFiles{…}
    
  • Use the right syntax to get the array parameter

    arr=("$@")
    

    instead of

    arr="$1"
    

Therefore

#!/bin/bash
function copyFiles() {
   arr=("$@")
   for i in "${arr[@]}";
      do
          echo "$i"
      done

}

array=("one 1" "two 2" "three 3")

copyFiles "${array[@]}"

Output is (my script has the name foo)

$ ./foo   
one 1
two 2
three 3

Solution 2:

If you want to pass one or more arguments AND an array, I propose this change to the script of @A.B.
Array should be the last argument and only one array can be passed

#!/bin/bash
function copyFiles() {
   local msg="$1"   # Save first argument in a variable
   shift            # Shift all arguments to the left (original $1 gets lost)
   local arr=("$@") # Rebuild the array with rest of arguments
   for i in "${arr[@]}";
      do
          echo "$msg $i"
      done
}

array=("one" "two" "three")

copyFiles "Copying" "${array[@]}"

Output:

$ ./foo   
Copying one
Copying two
Copying three

Solution 3:

You could also pass the array as a reference. i.e.:

#!/bin/bash

function copyFiles {
   local -n arr=$1

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

array=("one" "two" "three")

copyFiles array

but note that any modifications to arr will be made to array.