2013-03-20 27 views
35

Próbuję uzyskać prostą pętlę while pracującą w bashu, która używa dwóch warunków, ale po wypróbowaniu wielu różnych składni z różnych forów, nie mogę przestać rzucać błędu. Oto co mam:Skrypty Bash, wiele warunków w pętli while

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

Próbowałem również:

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

... jak również kilka innych konstrukcji. Chcę, aby ta pętla była kontynuowana podczas $stats is > 300 lub jeśli $stats = 0.

Odpowiedz

81

odpowiednie opcje są (w porządku rosnącym zalecenia)

# 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)) 

Niektóre Uwagi:

  1. Cytowanie rozszerzenia parametru w [[ ... ]] i ((...)) jest opcjonalne; Jeśli zmienna nie jest ustawiona, -gt i -eq przyjmie wartość 0.

  2. Korzystanie $ jest opcjonalne wewnątrz ((...)), ale używając go może pomóc uniknąć niezamierzonych błędów. Jeśli stats nie zostanie ustawione, wówczas ((stats > 300)) przyjmie stats == 0, ale (($stats > 300)) spowoduje błąd składni.

+0

Fantastyczna odpowiedź, niesamowicie dokładna – jake9115

+0

Bravo. klasyczny sposób na odpowiedź na post. Dobra robota. Zakładam, że możesz użyć tej samej składni z 'until' również, tak? – SaxDaddy

+0

@SaxDaddy Mniej więcej tak długo, jak starasz się poprawnie negować warunki: 'while [foo -o bar]' staje się 'until! [foo -o bar] ', ale' while foo || bar' staje się 'until! bla && ! pasek ". – chepner

1

Spróbuj:

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

[ jest wezwaniem do test. Nie służy tylko do grupowania, jak nawiasy w innych językach. Aby uzyskać więcej informacji, sprawdź numer man [ lub man test.

+1

Polecam '[[ponad' [. Zobacz mój komentarz do drugiej odpowiedzi. – danfuzz

+0

To jest w porządku. Użyłem [], ponieważ właśnie tego próbował użyć OP. Widziałem oba używane z powodzeniem. – drewmm

0

Dodatkowa [] na zewnętrznej drugiej składni jest niepotrzebna i może być myląca. Możesz ich używać, ale jeśli musisz, musisz mieć spacje między nimi.

alternatywnie:

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

Właściwie, '[[ogólnie jest preferowanym wbudowanym językiem, aby wprowadzić wyrażenie testowe. Ma kilka zalet w porównaniu ze starszą pojedynczą składnią "[". – danfuzz