J'ai le script bash suivant:
#!/bin/bash
upperlim=10
for i in {0..10}
do
echo $i
done
for i in {0..$upperlim}
do
echo $i
done
La première boucle for
(sans la variable upperlim
dans le contrôle de boucle) fonctionne correctement, mais la deuxième boucle for
(avec la variable upperlim
dans le contrôle de boucle) ne le fait pas. Existe-t-il un moyen de modifier la deuxième boucle for
pour qu'elle fonctionne? Merci pour votre temps.
La raison en est l'ordre dans lequel les choses se produisent dans bash. L'expansion de l'accolade se produit avant les variables sont développées. Pour atteindre votre objectif, vous devez utiliser le style C pour la boucle:
upperlim=10
for ((i=0; i<=upperlim; i++)); do
echo "$i"
done
Pour terminer cela dans votre style en utilisant uniquement des éléments intégrés, vous devez utiliser eval:
d=12
for i in `eval echo {0..$d}`
do
echo $i
done
Mais avec seq
:
lowerlimit=0
upperlimit=12
for i in $(seq $lowerlimit $upperlimit)
do
echo $i
done
Personnellement, je trouve que l'utilisation de seq
est plus lisible.
La manière POSIX
Si vous vous souciez de la portabilité, utilisez le exemple du standard POSIX :
i=2
END=5
while [ $i -le $END ]; do
echo $i
i=$(($i+1))
done
Production:
2
3
4
5
Les choses qui sont pas POSIX:
(( ))
Sans dollar, bien qu'il s'agisse d'une extension courante comme mentionné par POSIX lui-même .[[
. [
Suffit ici. Voir aussi: https://stackoverflow.com/questions/13542832/bash-if-difference-between-square-brackets-and-double-square-bracketsfor ((;;))
seq
{start..end}
, Et cela ne peut pas fonctionner avec les variables comme mentionné par le manuel de Bash .let i=i+1
: POSIX 7 2. Langage de commande shell ne contient pas le mot let
, et il échoue sur bash --posix
4.3.42le dollar à i=$i+1
pourrait être requis, mais je ne suis pas sûr. POSIX 7 2.6.4 Expansion arithmétique dit:
Si la variable Shell x contient une valeur qui forme une constante entière valide, incluant éventuellement un signe plus ou moins, alors les extensions arithmétiques
"$((x))"
et"$(($x))"
renverra la même valeur.
mais le lire littéralement n'implique pas que $((x+1))
se développe puisque x+1
n'est pas une variable.
Votre approche ne fonctionnera pas car dans bash l'accolade-expansion se produit avant l'expansion des paramètres. Vous devez développer la variable avant.
Vous pouvez contourner avec eval :
upperlim=10
eval '
for i in {0..'"$upperlim"'}
do
echo $i
done
'
Avec Boucle While :
upperlim=10
#with while
start=0
while [[ $start -le $upperlim ]]
do
echo "$start"
((start = start + 1))
done
Vous pouvez aussi le faire avec commande seq :
upperlim=10
#seq
for i in $(seq "$upperlim"); do
echo "$i"
done
Si vous souhaitez exécuter avec for i in {0..$upperlim}
vous devrez utiliser kornshell. par exemple:
#!/bin/ksh
upperlim=10
for i in {0..$upperlim}
do
echo $i
done