4 votes

Problème de manipulation des tableaux de paramètres Bash

J'ai un problème avec mon premier bash script. Je remplis un tableau dans une boucle for et quand j'essaie de récupérer un élément de ce tableau, je récupère toujours le premier élément.

for (( i = 0; i < ${#*}; i++ )); do
hash=$(md5 -q ${@:$i:1})
modifiedNames[$i]=${@:$i:1}$hash 
done

echo ${modifiedNames[1]}

par exemple si j'appelle mon script comme ceci : ./script.sh file1 file2 j'obtiens file1[file1hash]

Merci d'avance !

2voto

Nick Atoms Points 554

Je pense que votre boucle se comporte bizarrement car elle devrait commencer avec i = 1 et aller jusqu'à i = ${#*}. L'expansion de ${@:0:1} donne fichier1, tout comme ${@:1:1}.

Essayez for (( i = 1; i <= ${#*}; i++ ))

1voto

Win32 Points 1059

Vous itérez dans le tableau des arguments en commençant par 0, qui est le nom de la commande. Donc, si vous appelez votre script comme suit ./script.sh file1 file2 alors :

${@} = array(
   [0] = ./script,
   [1] = file1,
   [2] = file2
)

Donc, vous obtenez :

modifiedNamed = array(
   [0] = md5(./script),
   [1] = md5(file1)
)

Vous devriez changer votre for la boucle indexe vers :

for (( i = 1; i <= ${#*}; i++ )); do

1voto

je4d Points 4591

$@ n'est pas un vrai tableau - c'est un "paramètre spécial" de l'interpréteur de commandes, et vous devez être un peu plus prudent avec lui qu'avec les autres tableaux.

La raison du comportement que vous observez est que le comportement exact de la fonction ${parameter:length:offset} est un cas particulier lorsque parameter es @ et le comportement n'est pas cohérent avec le comportement que vous obtiendriez si @ était un vrai tableau.

Voici la documentation pertinente ( en gras c'est moi qui souligne) :

${ paramètre : décalage : longueur }

... Si paramètre est @, le résultat est longueur paramètres de position à partir de décalage . Si paramètre est @, le résultat est longueur paramètres positionnels commençant à décalage . ...

Le site paramètres de position sont $0 , $1 , $2 ..., donc avec cette syntaxe, il se comporte comme si $@ contenait le nom du script ( $0 ) ainsi que les paramètres du script ( $1 , $2 , ...). Ceci est incompatible avec "$@" en s'étendant à "$1" "$2" ... mais c'est la vie.

Vous devriez pouvoir simplifier les choses (et corriger le script) en créant un nouveau tableau au lieu d'utiliser $@ directement, c'est-à-dire

new_array=("$@")
for (( i = 0; i < ${#new_array}; i++ )); do
    hash=$(md5 -q ${new_array[@]:$i:1})
    modifiedNames[$i]=${new_array[@]:$i:1}$hash 
done

echo ${modifiedNames[1]}

0voto

DigitalRoss Points 80400

En fait, vous sont obtenir le deuxième élément, mais votre boucle met la même valeur dans [0] et dans [1].

Je ne suis pas certain de ce que vous essayez de faire mais il serait probablement plus facile d'itérer sur les arguments et de garder un compteur séparé pour le tableau.

n=0
for i in "$@"; do
  . . .
  n=$(($n + 1))
done

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X