web-dev-qa-db-fra.com

Comment passer un tableau comme argument à une fonction dans Bash

Comme nous le savons, dans la programmation bash, la façon de passer des arguments est $1, ..., $N. Cependant, j'ai trouvé qu'il n'était pas facile de passer un tableau comme argument à une fonction qui reçoit plus d'un argument. Voici un exemple:

f(){
 x=($1)
 y=$2

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

a=("jfaldsj jflajds" "LAST")
b=NOEFLDJF

f "${a[@]}" $b
f "${a[*]}" $b

Comme décrit, la fonction f reçoit deux arguments: le premier est affecté à x qui est un tableau, le second à y.

f peut être appelé de deux manières. La première façon, utilisez le "${a[@]}" comme premier argument, et le résultat est:

jfaldsj 
jflajds

La deuxième façon utilise le "${a[*]}" comme premier argument, et le résultat est:

jfaldsj 
jflajds 
LAST

Aucun résultat n'est comme je le souhaitais. Alors, y a-t-il quelqu'un qui a une idée de comment passer correctement un tableau entre des fonctions?

42
Red Lv

Vous ne pouvez pas passer un tableau, vous pouvez uniquement passer ses éléments (c'est-à-dire le tableau développé).

#! /bin/bash
function f() {
    a=("$@")
    ((last_idx=${#a[@]} - 1))
    b=${a[last_idx]}
    unset a[last_idx]

    for i in "${a[@]}" ; do
        echo "$i"
    done
    echo "b: $b"
}

x=("one two" "LAST")
b='even more'

f "${x[@]}" "$b"
echo ===============
f "${x[*]}" "$b"

L'autre possibilité serait de passer le tableau par son nom:

#! /bin/bash
function f() {
    name=$1[@]
    b=$2
    a=("${!name}")

    for i in "${a[@]}" ; do
        echo "$i"
    done
    echo "b: $b"
}

x=("one two" "LAST")
b='even more'

f x "$b"
67
choroba

Vous pouvez passer un tableau par référence à une fonction dans bash 4.3+. Cela vient probablement de ksh, mais avec une syntaxe différente. L'idée clé est de définir l'attribut -n:

show_value () # array index
{
    local -n array=$1
    local idx=$2
    echo "${array[$idx]}"
}

Cela fonctionne pour les tableaux indexés:

$ shadock=(ga bu zo meu)
$ show_value shadock 2
zo

Il fonctionne également pour les tableaux associatifs:

$ days=([monday]=eggs [tuesday]=bread [sunday]=jam)
$ show_value days sunday
jam

Voir également declare -n dans la page de manuel.

28
Edouard Thiel

Vous pouvez d'abord passer la valeur "scalaire". Cela simplifierait les choses:

f(){
  b=$1
  shift
  a=("$@")

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

a=("jfaldsj jflajds" "LAST")
b=NOEFLDJF

f "$b" "${a[@]}"

À ce stade, vous pouvez tout aussi bien utiliser directement les paramètres positionnels array-ish

f(){
  b=$1
  shift

  for i in "$@"   # or simply "for i; do"
  do
    echo $i
  done
  ....
}

f "$b" "${a[@]}"
6
glenn jackman

Cela résoudra le problème du passage du tableau à la fonction:

#!/bin/bash

foo() {
    string=$1
    array=($@)
    echo "array is ${array[@]}"
    echo "array is ${array[1]}"
    return
}
array=( one two three )
foo ${array[@]}
colors=( red green blue )
foo ${colors[@]}
0
Lavitha