126 votes

Comment passer un tableau comme argument de fonction ?

Je me suis débattu pendant un moment en passant un tableau comme argument mais ça ne marche pas de toute façon. J'ai essayé comme ci-dessous :

#! /bin/bash

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

}

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

copyFiles $array

Une réponse avec une explication serait la bienvenue.

Edit : En gros, je vais éventuellement appeler la fonction depuis un autre fichier script. Expliquez-moi les contraintes si possible.

180voto

A.B. Points 84870
  • L'expansion d'un tableau sans indice ne donne que le premier élément, utiliser

    copyFiles "${array[@]}"

    au lieu de

    copyFiles $array
  • Utilisez un she-bang

    #!/bin/bash
  • Utilisez la bonne syntaxe de fonction

    Les variantes valides sont

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

    au lieu de

    function copyFiles{…}
  • Utilisez la bonne syntaxe pour obtenir le paramètre de tableau

    arr=("$@")

    au lieu de

    arr="$1"

Par conséquent,

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

}

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

copyFiles "${array[@]}"

La sortie est (mon script a pour nom foo )

$ ./foo   
one 1
two 2
three 3

82voto

SBF Points 921

Si vous voulez passer un ou plusieurs arguments ET un tableau, je propose cette modification au script de @A.B.
Le tableau doit être le dernier argument et seulement un peut être passé

#!/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[@]}"

Ausgabe:

$ ./foo   
Copying one
Copying two
Copying three

37voto

Vous pouvez aussi passer le tableau comme une référence, c'est-à-dire.. :

#!/bin/bash

function copyFiles {
   local -n arr=$1

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

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

copyFiles array

mais notez que toute modification de arr sera apportée à array.

11voto

heemayl Points 85741

Il y a quelques problèmes. Voici le formulaire de travail :

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

}

array=("one" "two" "three")
copyFiles "${array[@]}"
  • Il faut qu'il y ait au moins un espace entre la déclaration de la fonction et {

  • Vous ne pouvez pas utiliser $array comme array est un tableau et non une variable. Si vous voulez obtenir toutes les valeurs d'un tableau, utilisez "${array[@]}"

  • Dans la déclaration de votre fonction principale, vous devez arr="$@" comme "${array[@]}" s'étendra aux valeurs indexées séparées par des espaces, si vous utilisez l'option $1 vous n'obtiendriez que la première valeur. Pour obtenir toutes les valeurs, utilisez arr="${arr[@]}" .

4voto

Voici un exemple un peu plus grand. Pour les explications, voir les commentaires dans le code.

#!/bin/bash -u
# ==============================================================================
# Description
# -----------
# Show the content of an array by displaying each element separated by a
# vertical bar (|).
#
# Arg Description
# --- -----------
# 1   The array
# ==============================================================================
show_array()
{
    declare -a arr=("${@}")
    declare -i len=${#arr[@]}
    # Show passed array
    for ((n = 0; n < len; n++))
    do
        echo -en "|${arr[$n]}"
    done
    echo "|"
}

# ==============================================================================
# Description
# -----------
# This function takes two arrays as arguments together with their sizes and a
# name of an array which should be created and returned from this function.
#
# Arg Description
# --- -----------
# 1   Length of first array
# 2   First array
# 3   Length of second array
# 4   Second array
# 5   Name of returned array
# ==============================================================================
array_demo()
{
    declare -a argv=("${@}")                           # All arguments in one big array
    declare -i len_1=${argv[0]}                        # Length of first array passad
    declare -a arr_1=("${argv[@]:1:$len_1}")           # First array
    declare -i len_2=${argv[(len_1 + 1)]}              # Length of second array passad
    declare -a arr_2=("${argv[@]:(len_1 + 2):$len_2}") # Second array
    declare -i totlen=${#argv[@]}                      # Length of argv array (len_1+len_2+2)
    declare __ret_array_name=${argv[(totlen - 1)]}     # Name of array to be returned

    # Show passed arrays
    echo -en "Array 1: "; show_array "${arr_1[@]}"
    echo -en "Array 2: "; show_array "${arr_2[@]}"

    # Create array to be returned with given name (by concatenating passed arrays in opposite order)
    eval ${__ret_array_name}='("${arr_2[@]}" "${arr_1[@]}")'
}

########################
##### Demo program #####
########################
declare -a array_1=(Only 1 word @ the time)                                       # 6 elements
declare -a array_2=("Space separated words," sometimes using "string paretheses") # 4 elements
declare -a my_out # Will contain output from array_demo()

# A: Length of array_1
# B: First array, not necessary with string parentheses here
# C: Length of array_2
# D: Second array, necessary with string parentheses here
# E: Name of array that should be returned from function.
#          A              B             C              D               E
array_demo ${#array_1[@]} ${array_1[@]} ${#array_2[@]} "${array_2[@]}" my_out

# Show that array_demo really returned specified array in my_out:
echo -en "Returns: "; show_array "${my_out[@]}"

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X