Menjalankan kembali perintah secara berkesinambungan saat selesai di Bash

62

Saya mencoba mencari cara sederhana untuk terus menjalankan kembali perintah kapan pun selesai, karena alasan apa pun (kesalahan atau lainnya).

Apa cara terbaik untuk mendekati ini?

EDIT: Saya belum cukup jelas sebelumnya. Saya perlu eksekusi berikutnya untuk menunggu sampai yang sebelumnya selesai.

EDIT 2: Hampir semua jawaban berfungsi dengan baik. Saya keliru mengira sebagian besar jawaban akan memotong proses atau menjalankannya sekali saja, tidak ada yang diinginkan.


sumber
1
Anda masih belum jelas. Ini akan membantu jika Anda menyebutkan program apa yang Anda jalankan.
Daniel Beck
1
-1 Pertanyaan ini tidak menunjukkan upaya penelitian apa pun, karena pengguna berkomentar bahwa jawaban tidak berfungsi bukannya benar-benar mencoba melakukan apa yang mereka sarankan.
Daniel Beck

Jawaban:

39

Ini menciptakan loop tak terbatas, mengeksekusi commandberulang-ulang.

while :
    do
        command
done
Dennis
sumber
Silakan lihat hasil edit untuk pertanyaan awal. Saya harus terus mengeksekusinya berulang kali, tidak hanya sekali.
8
@ calcifer Jawaban ini cukup berhasil. Ada sesuatu yang tidak biasa pada program Anda yang sejauh ini tidak satu pun dari empat pengguna menjawab dan Anda gagal menyebutkannya.
Daniel Beck
@ calcifer ini adalah loop tak terbatas. itu terus berulang sampai akhir waktu (yah, sampai skrip dihentikan anyways)
Nate Koppenhaver
1
Buruk saya, saya pikir ini (dan semua jawaban lainnya) akan memotong proses atau menjalankannya sekali saja, tidak ada yang diinginkan. Jadi ya, jawaban ini berhasil. Terima kasih.
1
satu versi baris while true; do echo 'Hit CTRL+C'; sleep 1; done
:,
107

The watchperintah akan mengulangi perintah selamanya dengan interval tertentu:

watch -n0 <command>

Pengaturan -nke nol secara efektif membuat interval tidak terjadi apa-apa (saya pikir ini benar-benar 0,1 detik).

watch juga memiliki manfaat tambahan untuk menyelaraskan output sehingga perubahan visual dapat dilihat dengan mudah, dan memiliki saklar untuk menyoroti perubahan dari proses terakhir.

Referensi: halaman manual arloji :

watch menjalankan perintah berulang kali, menampilkan outputnya (layar penuh pertama). Ini memungkinkan Anda untuk menonton perubahan output program dari waktu ke waktu. Secara default, program dijalankan setiap 2 detik; gunakan -n atau --interval untuk menentukan interval yang berbeda.

Arloji akan berjalan sampai terputus.

Paul
sumber
Silakan lihat hasil edit untuk pertanyaan awal.
6
Semua jawaban sejauh ini melakukan ini, termasuk yang ini. Linux tidak akan melakukan fork kecuali Anda secara khusus memintanya.
Paul
Saya tidak tahu tentang garpu, terima kasih.
Saya tidak dapat melihat output apa pun menggunakan metode ini.
Raffi Khatchadourian
@RaffiKhatchadourian Apakah Anda mengatakan jika Anda melakukannya watch lsdi direktori yang berisi file, Anda tidak mendapatkan apa-apa?
Paul
17

Solusi sederhana adalah:

yourcommand; !#

;memisahkan perintah, memungkinkan untuk beberapa perintah dalam satu baris ( Bash: Daftar )

!#memberitahu bash untuk "ulangi semua yang telah saya tulis sejauh ini di baris ini" ( Bash: Event-Designators )

Langit biru
sumber
1
Maaf, saya tidak cukup jelas. Saya harus terus mengeksekusinya berulang kali, tidak hanya sekali.
Terima kasih untuk ini, saya mencarinya, terutama karena yourcommand; !!tidak benar-benar bekerja dengan perintah pada baris yang sama, bagaimanapun, !#sepertinya berhasil. Tepuk tangan!
sdaau
; !#tidak bekerja pada ZSH, itu hanya memperluas pernyataan yang pada dasarnya mengkloningnya, itu tidak memicunya
kembalilah pada
7

Anda dapat merencanakan sebelumnya selama eksekusi perintah (asalkan tidak interaktif) dan masukkan !!yang akan mengeksekusi perintah sebelumnya lagi. Ini berfungsi misalnya selama ping -c 5.


Anda juga dapat mendefinisikan suatu fungsi di bash:

function repeat { "$@"; "$@"; }

Untuk bertahan, simpan di ~/.bashrc.

Kemudian, Anda dapat menjalankan perintah Anda seperti ini:

repeat ping -c5 heise.de

Jika itu perintah khusus yang ingin Anda jalankan berulang kali (dan bukan mis. Perintah apa pun ), Anda dapat mengganti "$@"potongan itu dengan perintah Anda yang sebenarnya, dan beri nama fungsi mis repeat_ping.


Untuk membuatnya menjadi infinite loop, Anda dapat melakukan apa yang disarankan @Dennis. Saya sarankan Anda menambahkan periode menunggu jika Anda ingin menggunakan ini dalam shell interaktif, seperti ini:

function repeat { while 1 ; do "$@" ; sleep 1 ; done; }

Kalau tidak, agak tidak nyaman untuk membatalkan loop tak terbatas ini menggunakan Ctrl-Z.

Daniel Beck
sumber
Silakan lihat hasil edit untuk pertanyaan awal.
6
@ calcifer Eksekusi ini menunggu hingga panggilan program kembali. Apakah program Anda terlepas dari shell dan kembali sebelum berhenti?
Daniel Beck
Buruk saya, saya pikir ini (dan semua jawaban lainnya) akan memotong proses atau menjalankannya sekali saja, tidak ada yang diinginkan. Jadi ya, jawaban ini berhasil. Terima kasih.
4

Berikan whileloop kondisi boolean seperti berikut:

#!/bin/bash

while true; do

    do_something && wait

done

Ini akan dieksekusi berulang-ulang sampai bash menerima sinyal untuk menghentikan proses. Biasanya dalam bentuk ctrl+c.

Anda juga dapat menggunakan watchperintah untuk menjalankan skrip berulang kali. Misalnya, jam sederhana di terminal bash Anda watchdapat terlihat seperti:

$ watch -t -n1 date +%T

The -tpilihan mengatakan watchuntuk tidak menampilkan judul dari proses sedang berjalan. Ini memberi Anda hasil bersih hanya dari perintah yang sedang diulang. The -n1pilihan memberitahu menonton untuk mengulang setiap ndetik. Dalam hal ini, -n1akan menjadi interval 1detik. Kemudian date +%Tperintah tersebut menunjukkan waktu pada saat penyelesaian perintah. Melakukan perintah ini akan memberi Anda jam aktif di terminal Anda.

Dan kemudian satu lagi metode yang tidak ada dalam jawaban lain akan menjadi panggilan fungsi yang tak terbatas.

do_something() { do_something }; do_something && wait

Ini pada dasarnya sama dengan whileloop boolean hanya menggunakan panggilan fungsi rekursif.

(sunting) Untuk menjaga sumber daya mesin Anda dalam pikiran, saya telah menambahkan && waitsehingga setiap kali proses dijalankan, loop akan "menunggu" sampai proses itu selesai dengan status keluar 0 sebelum iterasi berikutnya. Ini berguna dalam skrip shell interaktif.


sumber
1
Ada whilecontoh loop tetapi tidak menggunakan truesintaks boolean . Ada watchcontoh tetapi tidak memberikan banyak sintaks yang berguna. Saya menguraikan ini untuk siapa pun itu dapat membantu. Saya ingin memberikan manfaat praktis untuk ini. The whileLoop boolean juga bisa falsedan tidak mengeksekusi sampai kondisi benar terpenuhi. Ini sangat berguna.
1
@ Spittin'IT Menambahkan metode yang tidak digunakan dalam jawaban lain untuk kenyamanan Anda.
Cukup adil dan saya mengerti ... Saya hanya berkomentar ketika saya pergi melalui modul ulasan tetapi edit yang bagus dan tindak lanjut !!
Pimp Juice,
Bagaimana cara ifterus menjalankan kembali?
Kamil Maciorowski
Poin yang bagus Kamil. Lupa membuatnya lol rekursif. Diperbaiki dalam edit menggunakan fungsi yang memanggil dirinya sendiri dalam ifpernyataan.
0

Ini adalah metode lain yang saya gunakan untuk mengulangi perintah dalam bash. Ini mungkin terdengar konyol bagi sebagian orang karena tidak melibatkan penulisan naskah dan mungkin diketahui banyak orang. Tapi saya pikir ini layak disebut karena cepat dan ramah-pemula, dalam arti tidak ada banyak sintaks yang perlu diingat. Saya hanya menguji ini di gnome-terminal Ubuntu dan terminal lain mungkin tidak mendukung ini.

  1. Masukkan perintah di terminal sekali.
  2. Pilih perintah termasuk karakter baris baru dengan mouse.
  3. Salin pilihan menggunakan Ctrl-Insert atau menggunakan menu konteks (biasanya diakses dengan klik kanan).
  4. Gunakan Shift-Insert untuk menempelkan sebanyak yang Anda inginkan untuk menjalankan perintah.

Anda tidak perlu menunggu untuk menempelkan sampai setiap perintah selesai. Perintah yang disisipkan masuk ke antrian dan mereka mengeksekusi satu demi satu.

jayadeepk
sumber
0

Saya merasa cakep hari ini.

Baca dari salah satu aliran tanpa batas dan salurkan ke xargs

cat /dev/zero | xargs --null echo hello there

Jika Anda perlu sedikit istirahat di sana, kemungkinan besar Anda perlu mengeksekusi sh

cat /dev/zero | xargs --null sh -c "echo hello there && sleep 3"
Gua Jefferey
sumber