Bash Loop - Bagaimana cara menghentikan loop ketika saya menekan Control-C di dalam perintah?


35

Saya sedang menyusun beberapa direktori. Saya memiliki terminal bash yang terbuka dan menjalankan sesuatu seperti ini:

for DIR in * ; do rsync -a $DIR example.com:somewhere/ ; done

Namun jika saya ingin menghentikan semuanya, saya tekan Control-C. Itu menghentikan rsync, tetapi kemudian melanjutkan ke yang berikutnya. Dalam hal ini saya menyadari apa yang telah terjadi dan kemudian tekan Control-C seperti orang gila sampai semuanya bekerja lagi.

Apakah ada cara untuk 'memperbaiki' ini. Saya menginginkannya jadi jika saya memiliki loop seperti itu, dan tekan Control-C, itu akan mengembalikan saya ke bash shell saya.


6
Jawaban Dennis adalah yang benar, tetapi jika Anda tidak melakukannya, Anda tidak perlu 'menekannya seperti orang gila', tahan saja dan biarkan keyboard mengulanginya :-)
Kyle Brandt

Saya selalu tahan Cntl-C, umumnya berfungsi dengan baik.
Scott Alan Miller

Jawaban:


33
for DIR in * ; do rsync -a $DIR example.com:somewhere/ || break; done

Ini juga akan keluar dari loop jika menjalankan rsync individu gagal karena beberapa alasan.


4
Kiat tambahan: jika Anda berada di loop bersarang, dan ingin mengakhiri sepenuhnya, gunakan break 2(atau ganti "2" dengan jumlah loop bersarang yang ingin Anda hentikan).
Dolan Antenucci

26

Untuk memperluas jawaban Dennis, kode Anda mungkin terlihat seperti:

trap "echo Exited!; exit;" SIGINT SIGTERM

Untuk contoh yang berfungsi (yang melibatkan rsync), lihat http://gist.github.com/279849 .


Terima kasih, ini adalah solusi umum yang bekerja untuk saya
wi1

25

Anda dapat mengatur jebakan untuk Control-C.

trap <command> SIGINT

akan mengeksekusi commandketika Control-C ditekan. Cukup letakkan trappernyataan di suatu tempat di naskah Anda pada titik di mana Anda ingin menjadi efektif.



6

Saat Anda meletakkan string perintah di dalam tanda kurung, string akan bertindak sebagai satu proses, dan akan menerima SIGINT dan berakhir ketika Anda menekan Ctrl- C:

(for DIR in * ; do rsync -a $DIR example.com:somewhere/ ; done)

Tapi! Dalam kasus rsyncperintah, ini memungkinkan banyak sumber, sehingga kode yang Anda tulis akan lebih baik ditulis sebagai:

rsync -a * example.com:somewhere/

0

Saya cenderung untuk menempatkan perintah lain di loop saya yang dapat dengan mudah terganggu. Ini membutuhkan dua ctrl-C untuk ditekan.

for DIR in * ; do rsync -a $DIR example.com:somewhere/ ; sleep 1 ; done

Ini bukan solusi yang bagus untuk rsync ini, yang mungkin ingin Anda jalankan dengan cepat. Tapi itu bekerja dengan baik untuk loop lain, seperti ini:

while true ; do ping -c 10 example.com ; sleep 1 ; done

Loop ini akan mencari kembali alamat example.com setiap kali melalui loop, yang berguna jika Anda melihat perubahan DNS.

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.