2017-01-19 1 views
3

J'ai un script Bash que je ne peux pas comprendre comment citer une variable. Toute aide serait grandement appréciée.Comment passer un tableau dans une fonction Bash?

Ce code fonctionne parfaitement:

myfunction() { 
    for i in "${BASE_ARRAY[@]}" 
    do 

Je veux passer le nom de mon tableau comme une variable à la fonction que je peux le réutiliser avec d'autres tableaux. Voici le code que je suis en train d'échec:

myfunction() { 
    for i in "${$1[@]}" 
    do 

Je passe ce qui suit à la fonction:

myfunction BASE_ARRAY 
+0

Ressemble à un doublon de: http://stackoverflow.com/questions/1063347/passing-arrays-as-parameters-in-bash – codeforester

Répondre

4

Essayez ceci:

myfunction() { 
    local x="$1[@]" 
    for i in "${!x}" 
    do 

références indirectes dans Bash ressemblent "${!VARIABLE_CONTAINING_NAME_TO_EXPAND} Il est simple pour les variables qui ne sont pas des tableaux

Mais quand y Si vous devez accéder à un élément dans un tableau (ou à tous les éléments comme dans votre cas), vous devez mettre toute la référence dans la variable à développer.

+0

Que développe «$ 1 [@]'? Cela n'a aucun sens pour moi. Les paramètres de position seraient '$ @', et si vous vouliez regarder les éléments d'un tableau nommé par $ 1, il me semble que vous devriez l'évaluer. – Graham

+0

Supposons que $ 1 (le premier argument positionnel) contienne ARRAY_NAME. Ensuite, 1 $ [@] sera ajouté à ARRAY_NAME [@]. C'est l'étape $ {! X} qui va exécuter la récupération réelle de l'élément de tableau. – Fred

+1

Il pourrait être plus clair de l'écrire comme 'local x =" $ {1} [@] "' (bien que le code original soit entièrement équivalent). –

6

Je n'ai jamais eu de succès en passant les tableaux en fonctions.

Pour moi, les deux options sont toujours de passer contenu dans une fonction, ou (depuis bash 4.3) passer dans un nom de tableau qui sera accessible en utilisant une référence. Considérez l'exemple suivant.

#!/usr/bin/env bash 

myfunc() { 
     local -n arr=$1 
     printf '%s\n' "${arr[1]}" 
     arr[1]=HELLO 
} 

a=(one two three) 

myfunc a 
printf '%s\n' "${a[1]}" 

qui produit:

$ ./sample 
two 
HELLO 

Notez que local -n est comme declare -n en ce qu'elle ne fournit pas de copie locale du tableau, mais plutôt un pointeur locale au contenu original . Dans cet exemple, si vous modifiez $arr[], vous modifiez en fait le tableau d'origine, $a[].

La méthode traditionnelle de transmission du contenu d'un tableau à une fonction a été décrite tellement de fois ici sur StackOverflow qu'il est difficile de la mentionner; vous n'aurez aucune difficulté à trouver des exemples.

+0

C'est génial. Je n'en avais aucune idée. Merci d'avoir encore élargi mon cerveau. – Graham

+1

Ceci est très agréable et, oserais-je dire, excitant (au moins autant que la syntaxe du shell peut être). Mais c'est aussi très nouveau. J'ai un système CenOS 7 entièrement patché, et bash est toujours à la version 4.2.26. Pour une utilisation dans des scripts largement déployés sur des systèmes aléatoires, je crains que nous devrons attendre un bon moment. – Fred

+0

Cela semble vraiment similaire à la réponse de Fred. Y a-t-il un avantage à ajouter le -n à la variable locale? Est-ce plus rapide? Si je comprends bien, en utilisant le -n me permettra d'apporter des modifications au tableau réel à partir de la fonction? – tjohnson