2013-03-20 15 views
35

Tôi đang cố gắng để có được một vòng lặp đơn giản làm việc trong bash sử dụng hai điều kiện, nhưng sau khi thử nhiều cú pháp khác nhau từ các diễn đàn khác nhau, tôi không thể ngừng ném một lỗi. Dưới đây là những gì tôi có:Bash scripting, nhiều điều kiện trong khi vòng lặp

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

Tôi cũng đã cố gắng:

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

... cũng như một số người khác cấu trúc. Tôi muốn vòng lặp này tiếp tục trong khi $stats is > 300 hoặc nếu $stats = 0.

Trả lời

81

Các tùy chọn đúng là (theo thứ tự tăng dần giới thiệu):

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

Một số lưu ý:

  1. Trích dẫn các mở rộng tham số bên trong [[ ... ]]((...)) Là tùy chọn; nếu biến không được thiết lập, -gt-eq sẽ giả định một giá trị 0.

  2. Sử dụng $ là tùy chọn bên ((...)), nhưng sử dụng nó có thể giúp tránh các lỗi không chủ ý. Nếu stats không được đặt, thì ((stats > 300)) sẽ giả định stats == 0, nhưng (($stats > 300)) sẽ tạo ra lỗi cú pháp.

+0

Câu trả lời tuyệt vời, đáng kinh ngạc kỹ lưỡng – jake9115

+0

Bravo. một cách cổ điển để trả lời một bài đăng. Làm tốt. Tôi giả sử bạn có thể sử dụng cú pháp tương tự với 'cho đến khi', vâng? – SaxDaddy

+0

@SaxDaddy Nhiều hơn hoặc ít hơn, miễn là bạn cẩn thận để phủ nhận các điều kiện một cách chính xác: 'trong khi [foo -o bar]' trở thành 'cho đến khi! [foo -o bar] ', nhưng' trong khi foo || bar' trở thành 'cho đến khi! foo &&! bar'. – chepner

1

Hãy thử:

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

[ là một lời kêu gọi test. Nó không chỉ dành cho nhóm, như dấu ngoặc đơn trong các ngôn ngữ khác. Kiểm tra man [ hoặc man test để biết thêm thông tin.

+1

Tôi khuyên bạn nên '[[' over '['. Xem bình luận của tôi về câu trả lời khác. – danfuzz

+0

Thật công bằng. Tôi đã sử dụng [] vì đó là những gì OP đang cố gắng sử dụng. Tôi đã nhìn thấy cả hai được sử dụng với thành công. – drewmm

0

Thêm [] ở bên ngoài cú pháp thứ hai là không cần thiết và có thể gây nhầm lẫn. Bạn có thể sử dụng chúng, nhưng nếu bạn phải bạn cần có khoảng trống giữa chúng.

Hoặc:

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

Thực ra, '[[' thường được ưu tiên xây dựng để giới thiệu một biểu thức kiểm tra. Nó có một số ưu điểm so với cú pháp '[' duy nhất cũ hơn. – danfuzz