J'essaie de passer un tableau dans une fonction et toutes les modifications apportées au tableau sont reflétées à l'extérieur de la fonction
function update_array()
{
${1[0]}="abc" # trying to change zero-index array to "abc" ,
# bad substitution error
}
foo=(foo bar)
update_array foo[@]
for i in ${foo[@]}
do
echo "$i" # currently changes are not reflected outside the function
done
Mes questions sont
1) Comment puis-je accéder au tableau d'index, par exemple: tableau d'index zéro, dans la fonction, quelle est sa syntaxe
2) Comment puis-je apporter des modifications à ce tableau d'index afin que les modifications soient reflétées hors site également
Plusieurs problèmes, dans l’ordre logique de la résolution:
Avec votre instruction ${...}
dans update_array()
, la syntaxe ${..}
consiste à tiliser une variable et non à la définir.
Exemple:
foo[0]=abc # assigns 'abc' to foo[0]
Contournant cela, le nom du tableau est stocké dans une variable.
Ne fonctionne pas:
$1[0]=abc
Travail:
declare -g "$1[0]=abc" # -g arg is for a global variable
Passer un argument à update_array()
devrait transmettre le nom de la variable (foo
dans ce cas), pas le contenu du tableau. foo[@]
n'a rien de spécial, c'est une chaîne complètement normale (en Bash).
L'extension de variable avec ${foo[@]}
devrait être double.
La version de travail du code est ci-dessous:
update_array() {
declare -g "$1[0]=abc"
}
foo=(foo bar)
update_array foo
for i in "${foo[@]}"; do
echo "$i"
done
## Following line added by me for further clarification
declare -p foo
qui imprime correctement:
abc
bar
declare -a foo='([0]="abc" [1]="bar")'
La déclaration de variables peut ne pas être nécessaire dans Bash.1 Oui, vous pouvez utiliser declare
/typeset
pour plus de contrôle sur vos variables bash. Je pense donc qu'il n'est pas nécessaire de créer une fonction uniquement pour déclarer un nouveau tableau.
Ce script ci-dessous illustre une définition directe du tableau:
#!/bin/bash
function define_array_elements() {
# You can note the array elements being defined directly, without a prior
# definition of the variable.
for i in {1..10}; do
var_name[$i]="Field $i of the list"
done
}
define_array_elements > /dev/null
for i in {1..10}; do
echo "Field $i is: ${var_name[$i]}"
done
(Un exemple emprunté à Comment déclarer un tableau sans le définir? avec juste une petite modification.)
La réponse courte est: vous ne pouvez pas. Bash n'a pas de moyen de passer des variables par référence, il n'y a donc pas de moyen générique de le faire; il vous reste des hacks (laids) incluant indirection et/ou eval.
La prochaine version 4.3 de bash présentera les variables nameref, qui vous permettent de passer des variables par référence, mais même cette fonctionnalité n’est pas satisfaisante car vous risquez toujours la collision de noms.
# example of passing variables by reference in bash 4.3
update_array() {
declare -n array=$1
array[0]=abc
}
foo=( foo bar )
update_array foo
printf '<%s>\n' "${foo[@]}" # outputs <abc> and <bar>
Dans cet exemple, si le tableau s'appelait array
au lieu de foo
, il échouerait car declare -n array=array
est une erreur (declare: array: nameref variable self references not allowed
).
Voir http://mywiki.wooledge.org/BashFAQ/006 pour d'autres hacks.