Comment utilise-t-on une variable dans une boucle bash for? Si j'utilise simplement une boucle standard, elle fait ce que j'attends
for i in {0..3}
do
echo "do some stuff $i"
done
Cela fonctionne bien. Il boucle à travers 4 fois, de 0 à 3 inclus, imprimant mon message et mettant le décompte à la fin.
do some stuff 0
do some stuff 1
do some stuff 2
do some stuff 3
Lorsque j'essaie la même chose avec la boucle for suivante, il semble égaler une chaîne, ce qui n'est pas ce que je veux.
length=3
for i in {0..$length}
do
echo "do something right $i"
done
production:
do something right {0..3}
J'ai essayé
for i in {0.."$length"} and for i in {0..${length}} (both output was {0..3})
et
for i in {0..'$length'} (output was {0..$length})
et ils ne font pas tous les deux ce dont j'ai besoin. J'espère que quelqu'un pourra m'aider. Merci à l'avance de l'aide de tout expert bash pour les boucles.
Une façon utilise eval
:
for i in $( eval echo {0..$length} )
do
echo "do something right $i"
done
Remarque ce qui se passe lorsque vous définissez length=;ls
ou length=; rm *
(n'essayez pas ce dernier cependant).
en toute sécurité, en utilisant seq
:
for i in $( seq 0 $length )
do
echo "do something right $i"
done
ou vous pouvez utiliser la boucle for de style c, qui est également sûre:
for (( i = 0; i <= $length; i++ ))
do
echo "do something right $i"
done
En bash, l'expansion de l'accolade est la première tentative tentée donc, à ce stade, $length
ne sera pas remplacé.
La page de manuel de bash indique clairement:
Une expression de séquence prend la forme {x..y [.. incr]}, où x et y sont soit des entiers soit des caractères uniques ...
Il existe un certain nombre de possibilités, telles que l'utilisation:
pax> for i in $(seq 0 $length) ; do echo $i ; done
0
1
2
3
bien que cela puisse vous donner une grande ligne de commande si length
est énorme.
Une autre alternative consiste à utiliser la syntaxe de type C:
pax> for (( i = 0; i <= $length; i++ )) ; do echo $i; done
0
1
2
3
Les sous-titres d'accolade sont effectués avant tout autre, vous devez donc utiliser eval
ou un outil tiers comme seq
.
Exemple pour eval:
for i in `eval echo {0..$length}`; do echo $i; done
Ces informations se trouvent en fait dans man bash
:
Une expression de séquence prend la forme {x..y [.. incr]}, où x et y sont soit des entiers soit des caractères uniques, et incr, un incrément facultatif, est un entier. [...]
L'expansion d'accolade est effectuée avant toute autre extension, et tout caractère spécial à d'autres extensions est conservé dans le résultat. Il est strictement textuel. Bash n'applique aucune interprétation syntaxique au contexte de l'expansion ou au texte entre les accolades.