2009-08-17 35 views
449

Tôi gặp sự cố khi sắp xếp kết hợp đúng dấu chấm phẩy và/hoặc dấu ngoặc nhọn. Tôi muốn làm điều này, nhưng như một lớp lót từ dòng lệnh:Cú pháp cho một dòng vô hạn Bash duy nhất trong khi vòng lặp

while [ 1 ] 
do 
    foo 
    sleep 2 
done 
+4

thay thế dòng mới bằng dấu chấm phẩy. Các công trình tương tự cho các vòng lặp. – Tom

+19

@Tom: không phải lúc nào cũng hiệu quả. sau khi làm, bạn phải có lệnh đầu tiên, không phải là dấu chấm phẩy –

Trả lời

835
while true; do foo; sleep 2; done 

Bằng cách này, nếu bạn gõ nó như là một multiline (như bạn đang hiển thị) tại dấu nhắc lệnh và sau đó gọi lịch sử với mũi tên lên, bạn sẽ nhận được nó trên một dòng duy nhất, đúng dấu câu.

$ while true 
> do 
> echo "hello" 
> sleep 2 
> done 
hello 
hello 
hello 
^C 
$ <arrow up> while true; do echo "hello"; sleep 2; done 
+230

+1 cho đồng hồ và vần điệu. Đó là một sự ghi nhớ tuyệt vời: "trong khi * true * làm * foo * ngủ * quá * la di da": D – Shabbyrobe

+1

"nếu bạn gõ nó như là một multiline (như bạn đang hiển thị) tại dấu nhắc lệnh và sau đó gọi lịch sử với mũi tên lên, bạn sẽ nhận được nó trên một dòng duy nhất, đúng dấu chấm câu. " không đúng với tôi. –

+0

@VincentScheib, kiểm tra tùy chọn 'cmdhist' nếu bạn đang sử dụng bash? –

23

Bạn có thể sử dụng dấu chấm phẩy để báo cáo riêng biệt:

$ while [ 1 ]; do foo; sleep 2; done 
+0

Tôi thích câu trả lời này vì nó giải thích khi nào và tại sao; (dấu chấm phẩy) là bắt buộc. –

6

Tôi thích sử dụng các dấu chấm phẩy chỉ dành cho báo cáo kết quả KHI, và & & điều hành để thực hiện vòng lặp làm nhiều hơn là một điều. ..

Vì vậy, tôi luôn làm như thế này

while true ; do echo Launching Spaceship into orbit && sleep 5s && /usr/bin/launch-mechanism && echo Launching in T-5 && sleep 1s && echo T-4 && sleep 1s && echo T-3 && sleep 1s && echo T-2 && sleep 1s && echo T-1 && sleep 1s && echo liftoff ; done 
+1

Vâng, việc sử dụng '&&' trong vòng lặp giống như bất kỳ thời điểm nào khác thực sự không phải là nó. Bạn có cần điều thứ hai xảy ra chỉ khi điều đầu tiên xảy ra, sau đó sử dụng '&&' else ';' suffices. Thực sự, bạn muốn giữ nội dung của vòng lặp đó ngắn và đơn giản, lý tưởng chỉ là một lệnh, do đó, một hàm hoặc một tập lệnh. – thecoshman

1

Nếu tôi có thể đưa ra hai ví dụ thực tế (với một chút "cảm xúc").

này viết tên của tất cả các file kết thúc với ".jpg" trong thư mục "img":

for f in *; do if [ "${f#*.}" == 'jpg' ]; then echo $f; fi; done 

này xóa chúng:

for f in *; do if [ "${f#*.}" == 'jpg' ]; then rm -r $f; fi; done 

Chỉ cần cố gắng để đóng góp.

+3

Dễ nói hơn: '' 'cho f trong * .jpg; echo echo $; done''' – JKnight

+1

@JKnight - cho những ví dụ này, bạn sẽ không chỉ làm ** 'ls -1 * .jpg' ** và **' rm * .jpg' ** –

+2

Cả hai đều không phải là vòng lặp vô hạn và không phải trong khi vòng lặp. – Marian

126

Cũng có thể sử dụng lệnh ngủ trong điều kiện của thời gian. Làm cho một lớp lót trông sạch sẽ hơn.

while sleep 2; do echo thinking; done 
+1

điều cần biết !! –

+5

Điều này không chỉ thay đổi cú pháp - nó sẽ thực hiện lệnh * sau * ngủ. Trong câu trả lời trước, lệnh được thực hiện ngay lập tức.Chỉ cần một cái gì đó cần lưu ý. – DanGordon

55

Colon phải lúc nào cũng "true":

while :; do foo; sleep 2; done 
+11

Tại sao ruột kết luôn đúng? – Michelle

+5

@Pineapple Under the Sea: Từ trang bash man: (trong phần SHELL BUILTIN COMMANDS) ': [đối số]' Không có hiệu lực; lệnh không làm gì ngoài việc mở rộng các đối số và thực hiện bất kỳ chuyển hướng được chỉ định nào. Mã trả về không được trả lại. –

+2

cú pháp này được khuyến nghị là: là một phần của shell, tức là: là một lệnh nội trang hệ vỏ. – avner

18

Bạn cũng có thể tận dụng until lệnh:

until ((0)); do foo; sleep 2; done 

Lưu ý rằng trái ngược với while, until sẽ thực thi các lệnh bên trong vòng lặp miễn là điều kiện thử nghiệm có trạng thái thoát không phải là 0.


Sử dụng một vòng lặp while:

while read i; do foo; sleep 2; done < /dev/urandom 

Sử dụng một vòng lặp for:

for ((;;)); do foo; sleep 2; done 

Một cách khác sử dụng until:

01.
until [ ]; do foo; sleep 2; done 
+4

+1 cho giải pháp thay thế. – glen3b

5

Vòng lặp vô hạn rất đơn giản ..:)

while true ; do continue ; done 

Cha câu hỏi của bạn nó sẽ là:

while true; do foo ; sleep 2 ; done 
2

Đối với quá trình đơn giản theo dõi sử dụng watch thay

0

Bạn có thể thử này quá CẢNH BÁO: này bạn không nên làm nhưng kể từ khi câu hỏi là yêu cầu cho vòng lặp vô hạn không có kết thúc ... đây là cách bạn có thể làm điều đó.

while [[ 0 -ne 1 ]]; do echo "it's looping"; sleep 2; done 
+0

Tại sao bạn thậm chí sẽ làm điều đó? –

+1

vì Brian Deacon đã đăng câu hỏi như một vòng lặp infinte. Đó là nhiều cách để làm cho một con mèo trở thành một con mèo, tất cả là –

1

Nếu bạn muốn vòng lặp while để dừng lại sau khi một số điều kiện, và lệnh foo bạn trả khác không khi điều kiện này được đáp ứng sau đó bạn có thể nhận được vòng lặp để phá vỡ như thế này:

while foo; do echo 'sleeping...'; sleep 5; done; 

Ví dụ: nếu lệnh foo xóa mọi thứ theo lô và trả về 1 khi không còn gì để xóa.

Điều này hoạt động tốt nếu bạn có tập lệnh tùy chỉnh cần chạy lệnh nhiều lần cho đến khi một số điều kiện. Bạn viết kịch bản để thoát với 1 khi điều kiện được đáp ứng và thoát ra với 0 khi nó sẽ chạy lại. Ví dụ: giả sử bạn có tập lệnh python batch_update.py cập nhật 100 hàng trong cơ sở dữ liệu và trả về 0 nếu có nhiều cập nhật và 1 nếu không còn nữa. Lệnh sau sẽ cho phép bạn cập nhật các hàng 100 tại một thời điểm với việc ngủ trong 5 giây giữa các bản cập nhật:

while batch_update.py; do echo 'sleeping...'; sleep 5; done; 
+0

và bạn sẽ thoát ra sao? –

+0

Bạn thực hiện lệnh thoát 'foo' bằng mã '1' khi bạn muốn vòng lặp while ngắt. Tôi đã cập nhật câu trả lời của mình bằng một ví dụ. –

Các vấn đề liên quan