2012-03-28 17 views
22

Hier myscript.sh

#!/bin/bash 
for i in {1..$1}; 
do 
    echo $1 $i; 
done 

Wenn ich myscript.sh 3 laufen die Ausgabe

3 {1..3} 

statt

3 1 
3 2 
3 3 

Offensichtlich $3 enthält den richtigen Wert, also warum nicht for i in {1..$1} verhalten sich gleich, als ob ich hatte for i in {1..3} direkt geschrieben?

+1

Ihr Beispielskript in beiden ksh93 arbeiten und zsh . –

Antwort

43

Sie einen C-Stil verwenden sollte Schleife um dies zu erreichen:

for ((i=1; i<=$1; i++)); do 
    echo $i 
done 

Dies vermeidet externe Befehle und unangenehme Eval-Anweisungen.

+0

Funktioniert nicht für mich 'test.sh: Zeile 1: ((<: Syntaxfehler: Operand erwartet (Fehler Token ist" <= ")' – Temak

+0

@Temak verwenden Sie 'Bash'? Ist Ihr Shebang' #!/bin/bash' oder '#!/bin/sh'? – jordanm

+0

@jordann, Datei enthält nur diese 3 Zeilen. Ich verwende GNU bash, Version 4.3.11 (1) -release (x86_64-pc- linux-gnu) Ich führe das Skript 'bash test.sh' – Temak

18

Da die Klammererweiterung vor der Erweiterung der Variablen auftritt. http://www.gnu.org/software/bash/manual/bashref.html#Brace-Expansion.

Wenn Sie Klammern verwenden, könnten Sie so grimmig etwas wie folgt aus:

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

Zusammenfassung: Bash ist abscheulich.

+1

Heh, +1 für die Antwort, -0,5 für die Gemeinheit. –

+1

@Glennjackman: Wow, du sagst, dass die unzähligen Expansions- und Flucht-Regeln von Bash nicht abscheulich sind? –

+0

Ich fühle mich dreckig, wenn ich in einer Antwort mit "eval" +1 sage. Re: vile: 'Bash' ist nicht abscheulich, aber es ist ein bisschen wie getreidegetränk getrunken. Manche Leute scheinen es zu mögen, aber es ist schwer, zuerst nicht zu würgen, und je mehr du es machst, desto weniger stört dich das. – Sorpigal

11

können Sie seq Befehl:

for i in `seq 1 $1` 

Oder können Sie den C-Stil for...loop verwenden:

for((i=1;i<=$1;i++)) 
+0

Eine C-for-Schleife wird gegenüber dem externen seq-Befehl bevorzugt. – jordanm

+0

@jordanm Es ist eine gute Idee. – kev

+0

sehr gut, mit Seq können Sie Schritt ändern! –

1

Ich weiß, Sie haben bash in der Überschrift erwähnt, aber ich würde hinzufügen, dass "für i in {$ 1 .. $ 2}" wie vorgesehen in zsh funktioniert. Wenn auf Ihrem System zsh installiert ist, können Sie einfach Ihren shebang in zsh ändern.

Die Verwendung von zsh mit dem Beispiel 'für i in {$ 1 .. $ 2}' hat auch den zusätzlichen Vorteil, dass $ 1 weniger als $ 2 sein kann und es immer noch funktioniert, etwas, das ziemlich viel Unsinn erfordert Diese Art von Flexibilität mit einem C-Stil für die Schleife.

0

Dies ist eine Möglichkeit, Variablen zu erweitern innerhalb Zahnspange ohne eval:

end=3 
declare -a 'range=({'"1..$end"'})' 

Wir haben jetzt eine schöne Auswahl von Zahlen haben:

for i in ${range[@]};do echo $i;done 
1 
2 
3 
Verwandte Themen