it-swarm.com.de

Ist es in bash möglich, eine Ganzzahlvariable in der Schleifensteuerung einer for-Schleife zu verwenden?

Ich habe das folgende Bash-Skript:

#!/bin/bash

upperlim=10

for i in {0..10}
do
echo $i
done

for i in {0..$upperlim}
do
echo $i
done

Die erste for Schleife (ohne die Variable upperlim in der Schleifensteuerung) funktioniert einwandfrei, aber die zweite for Schleife (mit) die Variable upperlim in der Schleifensteuerung) nicht. Gibt es eine Möglichkeit, die zweite for - Schleife so zu ändern, dass sie funktioniert? Vielen Dank für Ihre Zeit.

70
Andrew

Der Grund dafür ist die Reihenfolge, in der die Dinge in Bash auftreten. Die Klammererweiterung erfolgt vor Variablen werden erweitert. Um Ihr Ziel zu erreichen, müssen Sie den C-Stil für die Schleife verwenden:

upperlim=10

for ((i=0; i<=upperlim; i++)); do
   echo "$i"
done
67
jordanm

Um dies in Ihrem Stil nur mit integrierten Funktionen zu vervollständigen, müssen Sie eval verwenden:

d=12

for i in `eval echo {0..$d}`
do
echo $i
done

Aber mit seq:

lowerlimit=0
upperlimit=12

for i in $(seq $lowerlimit $upperlimit)
do
echo $i
done

Persönlich finde ich die Verwendung von seq besser lesbar.

31
Jodie C

Der POSIX-Weg

Wenn Sie sich für Portabilität interessieren, verwenden Sie das Beispiel aus dem POSIX-Standard :

i=2
END=5
while [ $i -le $END ]; do
    echo $i
    i=$(($i+1))
done

Ausgabe:

2
3
4
5

Dinge, die nicht POSIX sind:

Ihr Ansatz funktioniert nicht, da in Bash die Klammererweiterung vor der Parametererweiterung erfolgt. Sie müssen die Variable vorher erweitern.

Sie können mit eval :

upperlim=10
eval '
        for i in {0..'"$upperlim"'}
        do
                echo $i
        done
'

Mit While-Schleife :

upperlim=10
#with while
start=0
while [[ $start -le $upperlim ]]
do
    echo "$start"
    ((start = start + 1))
done

Sie können dies auch mit Befehl seq tun:

upperlim=10
#seq
for i in $(seq "$upperlim"); do
  echo "$i"
done

Wenn Sie mit for i in {0..$upperlim} Ausführen möchten, müssen Sie kornshell verwenden. z.B:

#!/bin/ksh
upperlim=10

for i in {0..$upperlim}
do
        echo $i
done
1