2013-06-19 7 views
10

Wie benutzt man eine Variable in einer Bash for-Schleife? Wenn ich nur einen Standard für die Schleife verwenden, tut es das, was ich erwarte, dassWie verwendet man Variablen in einer Bash for-Schleife

for i in {0..3} 
do 
    echo "do some stuff $i" 
done 

Dies funktioniert gut. Es läuft 4 mal durch, 0 bis 3 inklusive, druckt meine Nachricht und setzt die Zählung am Ende.

do some stuff 0 
do some stuff 1 
do some stuff 2 
do some stuff 3 

Wenn ich versuche, das gleiche mit der for-Schleife folgt, scheint es eine Zeichenfolge gleich, was nicht das, was ich will.

length=3 
for i in {0..$length} 
do 
    echo "do something right $i" 
done 

Ausgang:

do something right {0..3} 

Ich habe

versucht
for i in {0.."$length"} and for i in {0..${length}} (both output was {0..3}) 

und

for i in {0..'$length'} (output was {0..$length}) 

und sie beide nicht tun, was ich brauche. Hoffentlich kann mir jemand helfen. Vielen Dank im Voraus für die Hilfe eines Bash-Experten mit for-Schleifen.

Antwort

12

Ein Weg ist mit eval:

for i in $(eval echo {0..$length}) 
do 
     echo "do something right $i" 
done 

Hinweis was passiert, wenn Sie setzen length=;ls oder length=; rm * (nicht versuchen, die letztere obwohl).

sicher, mit seq:

for i in $(seq 0 $length) 
do 
     echo "do something right $i" 
done 

oder können Sie die c-style for-Schleife verwenden, die auch sicher ist:

for ((i = 0; i <= $length; i++)) 
do 
     echo "do something right $i" 
done 
+3

+1 nicht ein Fan von 'eval' aber wie die Art, wie Sie verschiedene Optionen in dieser Antwort geben. –

+1

C-Style-Loop ist offensichtlich die beste Option. –

4

In der bash Klammer Expansion ist die erste Schritt versucht, zu diesem Zeitpunkt $length wurde nicht ersetzt worden.

Die Manpage für bash Staaten klar:

Eine Sequenz Ausdruck hat die Form {x..y [.. incr]}, wobei x und y sind entweder ganze Zahlen oder einzelne Zeichen ...

Es gibt eine Reihe von Möglichkeiten, wie die Verwendung von:

pax> for i in $(seq 0 $length) ; do echo $i ; done 
0 
1 
2 
3 

obwohl das kann Ihnen eine große Kommandozeile wenn length ist massiv.

Eine weitere Alternative ist die C-ähnliche Syntax zu verwenden:

pax> for ((i = 0; i <= $length; i++)) ; do echo $i; done 
0 
1 
2 
3 
3

Brace Substitutionen sind vor allen anderen durchgeführt, so müssen Sie wie seqeval oder ein Drittanbieter-Tool verwenden.

Beispiel für eval:

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

Diese Informationen können tatsächlich in man bash finden:

Eine Sequenz Ausdruck nimmt die Form {x..y [.. incr]}, wo x und y sind entweder ganze Zahlen oder einzelne Zeichen und incr, ein optionales Inkrement, ist eine ganze Zahl. [...]

Brace Expansion wird vor allen anderen Erweiterungen durchgeführt, und alle Zeichen speziellen zu anderen Erweiterungen werden im Ergebnis erhalten. Es ist streng textlich. Bash wendet keine syntaktische Interpretation auf den Kontext der Erweiterung oder den Text zwischen den geschweiften Klammern an.

Verwandte Themen