Sintaks untuk Bash baris tunggal infinite while


636

Saya mengalami masalah dengan kombinasi titik koma dan / atau kawat gigi yang tepat. Saya ingin melakukan ini, tetapi sebagai one-liner dari baris perintah:

while [ 1 ]
do
    foo
    sleep 2
done

4
ganti baris baru dengan titik koma. Hal yang sama berlaku untuk loop.
Tom

23
@ Tom: itu tidak selalu berhasil. setelah do, Anda harus memiliki perintah pertama, bukan titik koma
Stefano Borini

Jawaban:


1233
while true; do foo; sleep 2; done

Ngomong-ngomong, jika Anda mengetiknya sebagai multiline (seperti yang Anda tunjukkan) di command prompt dan kemudian memanggil histori dengan panah ke atas, Anda akan mendapatkannya di satu baris, diselingi dengan benar.

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

2
"Jika Anda mengetiknya sebagai multiline (seperti yang Anda tunjukkan) pada command prompt dan kemudian memanggil histori dengan panah ke atas, Anda akan mendapatkannya pada satu baris, diselingi dengan benar." itu tidak benar untukku.
Vincent Scheib

@VincentScheib, centang cmdhistopsi jika Anda menggunakan bash?
Alok Singhal

Luar biasa! Bekerja dengan sempurna pada Mavericks (Mac OS-X 10.9) dan memungkinkan saya untuk menjalankan vpn. Openconnect terputus setelah beberapa jam dengan kesalahan cookie yang buruk. Jadi saya meletakkan perintah openconnect dalam skrip shell, sudo su untuk menjadi root, dan gunakan baris cmd ini: while true; do sh /Users/myuser/bin/vpn ; done
Blisterpeanuts

170

Juga dimungkinkan untuk menggunakan perintah tidur dalam kondisi sementara. Membuat one-liner tampak lebih bersih.

while sleep 2; do echo thinking; done

16
Nah ini tidak lebih dari sekedar mengubah sintaks - itu akan menjalankan perintah setelah tidur. Di jawaban sebelumnya, perintah dieksekusi segera. Hanya sesuatu yang perlu diperhatikan.
DanGordon

@DanGordon while echo thinking ; do sleep 2 ; done Tentu saja jika perintah [while] gagal, loop keluar, jadi Anda harus while echo thinking || true ; do sleep 2 ; donetetapi kemudian Anda kembali kewhile true ; ...
Brian Carcich

69

Usus selalu "benar":

while :; do foo; sleep 2; done

15
mengapa usus besar selalu benar?
Jürgen Paul

8
@ Pineapple Under the Sea: Dari halaman bash man: (di bagian SHELL BUILTIN PERINTAH) : [arguments] Tidak ada efek; perintah tidak melakukan apa-apa selain memperluas argumen dan melakukan pengalihan tertentu. Kode keluar nol dikembalikan.
Adrian W

2
sintaks ini direkomendasikan sebagai: adalah bagian dari shell itu sendiri yaitu: adalah perintah builtin shell.
avner

@analytik jadi apa maksudmu plus atau minus? ;-)
Brian Carcich

33

Anda dapat menggunakan titik koma untuk memisahkan pernyataan:

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

3
Saya suka jawaban ini karena ini menjelaskan kapan dan mengapa; (titik koma) diperlukan.
Tn. AndreasGeo

29

Anda juga dapat menggunakan untilperintah:

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

Perhatikan bahwa berbeda dengan while, untilakan menjalankan perintah di dalam loop selama kondisi tes memiliki status keluar yang tidak nol.


Menggunakan whileloop:

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

Menggunakan forloop:

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

Cara lain menggunakan until:

until [ ]; do foo; sleep 2; done

The until ((0)); do foo; sleep 2; donetampaknya tidak bekerja. Itu terus menerus tanpa batas.
030

11

Loop tak terbatas yang sangat sederhana .. :)

while true ; do continue ; done

Dari pertanyaan Anda:

while true; do foo ; sleep 2 ; done

8

Saya suka menggunakan titik koma hanya untuk pernyataan WHILE, dan operator && untuk membuat loop melakukan lebih dari satu hal ...

Jadi saya selalu melakukannya seperti ini

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
Nah, penggunaan &&dalam loop adalah sama seperti waktu lainnya sebenarnya bukan. Apakah Anda perlu hal kedua terjadi hanya jika yang pertama terjadi, kemudian gunakan yang &&lain ;cukup. Sungguh, Anda ingin menjaga isi loop itu pendek dan sederhana, idealnya hanya satu perintah, jadi fungsi atau skrip.
thecoshman


6

Menggunakan while:

while true; do echo 'while'; sleep 2s; done

Menggunakan forLoop:

for ((;;)); do echo 'forloop'; sleep 2; done

Menggunakan Recursion, (sedikit berbeda dari di atas, interupsi keyboard tidak akan menghentikannya)

list(){ echo 'recursion'; sleep 2; list; } && list;

5

Jika Anda ingin loop sementara berhenti setelah beberapa kondisi, dan fooperintah Anda mengembalikan non-nol ketika kondisi ini terpenuhi maka Anda bisa mendapatkan loop untuk istirahat seperti ini:

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

Misalnya, jika fooperintahnya menghapus hal-hal dalam batch, dan mengembalikan 1 ketika tidak ada yang tersisa untuk dihapus.

Ini berfungsi dengan baik jika Anda memiliki skrip khusus yang perlu menjalankan perintah berkali-kali hingga beberapa syarat. Anda menulis skrip untuk keluar 1saat kondisi terpenuhi dan keluar 0saat harus dijalankan kembali.

Misalnya, Anda memiliki skrip python batch_update.pyyang memperbarui 100 baris dalam database dan mengembalikan 0jika ada lebih banyak untuk memperbarui dan 1jika tidak ada lagi. Perintah berikut akan memungkinkan Anda untuk memperbarui baris 100 sekaligus dengan tidur selama 5 detik antara pembaruan:

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

dan bagaimana Anda akan keluar?
AK_

Anda membuat fooperintah keluar dengan kode 1saat Anda ingin loop sementara terputus. Saya telah memperbarui jawaban saya dengan sebuah contoh.
Yep_It's_Me

2

Jika saya bisa memberikan dua contoh praktis (dengan sedikit "emosi").

Ini menulis nama semua file yang diakhiri dengan ".jpg" di folder "img":

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

Ini menghapus mereka:

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

Hanya berusaha berkontribusi.


1
@JKnight - untuk contoh-contoh ini, tidakkah Anda hanya melakukan ls -1 *.jpgdanrm *.jpg
Kevin Fegan

2
Keduanya bukan loop tak terbatas dan tidak saat loop.
Marian

2

Anda dapat mencoba ini juga PERINGATAN: ini sebaiknya tidak Anda lakukan tetapi karena pertanyaannya adalah meminta infinite loop tanpa akhir ... ini adalah bagaimana Anda dapat melakukannya.

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

Mengapa Anda melakukan itu?
gniourf_gniourf

2
karena Brian Deacon yang memposting pertanyaan ingin seperti loop infinte. Ini lebih dari satu cara menguliti kucing itu saja
grepit
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.