2013-03-20 23 views
35

Ich versuche, eine einfache While-Schleife in Bash, die zwei Bedingungen verwendet, aber nach dem Versuch, viele verschiedene Syntax aus verschiedenen Foren, ich kann nicht aufhören zu werfen einen Fehler. Hier ist, was ich habe:Bash Scripting, mehrere Bedingungen in While-Schleife

while [ $stats -gt 300 ] -o [ $stats -eq 0 ] 

Ich habe auch versucht:

while [[ $stats -gt 300 ] || [ $stats -eq 0 ]] 

... sowie einige andere Konstrukte. Ich möchte diese Schleife fortsetzen, während $stats is > 300 oder wenn $stats = 0.

Antwort

81

Die richtigen Optionen sind (in der Reihenfolge der Empfehlung zu erhöhen):

# Single POSIX test command with -o operator (not recommended anymore). 
# Quotes strongly recommended to guard against empty or undefined variables. 
while [ "$stats" -gt 300 -o "$stats" -eq 0 ] 

# Two POSIX test commands joined in a list with ||. 
# Quotes strongly recommended to guard against empty or undefined variables. 
while [ "$stats" -gt 300 ] || [ "$stats" -eq 0 ] 

# Two bash conditional expressions joined in a list with ||. 
while [[ $stats -gt 300 ]] || [[ $stats -eq 0 ]] 

# A single bash conditional expression with the || operator. 
while [[ $stats -gt 300 || $stats -eq 0 ]] 

# Two bash arithmetic expressions joined in a list with ||. 
# $ optional, as a string can only be interpreted as a variable 
while ((stats > 300)) || ((stats == 0)) 

# And finally, a single bash arithmetic expression with the || operator. 
# $ optional, as a string can only be interpreted as a variable 
while ((stats > 300 || stats == 0)) 

Einige Anmerkungen:

  1. die Parametererweiterungen innerhalb [[ ... ]] und ((...)) Zitiert es ist optional; wenn die Variable nicht gesetzt ist, -gt und -eq einen Wert von 0.

  2. nehmen Verwendung $ innerhalb ((...)) optional ist, aber es verwendet, kann unbeabsichtigte Fehler vermeiden helfen. Wenn stats nicht festgelegt ist, wird ((stats > 300))stats == 0 annehmen, aber (($stats > 300)) wird einen Syntaxfehler erzeugen.

+0

Fantastische Antwort, erstaunlich gründlich – jake9115

+0

Bravo. eine klassische Art, einen Beitrag zu beantworten. Gut gemacht. Ich nehme an, Sie können die gleiche Syntax auch mit 'bis 'verwenden, ja? – SaxDaddy

+0

@SaxDaddy Mehr oder weniger, solange Sie darauf achten, die Bedingungen richtig zu negieren: 'while [foo -o bar]' wird 'bis! [foo -o bar] ', aber' während foo || bar' wird 'bis! foo &&! bar'. – chepner

1

Versuchen:

while [ $stats -gt 300 -o $stats -eq 0 ] 

[ ist ein Aufruf an test. Es ist nicht nur zum Gruppieren, wie Klammern in anderen Sprachen. Weitere Informationen finden Sie unter man [ oder man test.

+1

Ich empfehle '[[' über '['. Siehe meinen Kommentar zu der anderen Antwort. – danfuzz

+0

Das ist fair. Ich habe [] benutzt, weil das der OP versucht hat zu verwenden. Ich habe beide mit Erfolg benutzt gesehen. – drewmm

0

Die extra [] auf der Außenseite Ihrer zweiten Syntax sind unnötig und möglicherweise verwirrend. Sie können sie verwenden, aber wenn Sie müssen, müssen Sie Leerzeichen zwischen ihnen haben.

Alternativ:

while [ $stats -gt 300 ] || [ $stats -eq 0 ] 
+0

Eigentlich ist '[[]' im Allgemeinen das bevorzugte eingebaute, um einen Testausdruck einzuführen. Es hat mehrere Vorteile gegenüber der älteren single '[' Syntax. – danfuzz