Saya hanya melompat ke dunia unix dari dunia yang berbeda, dan ingin tahu apakah
while true
do
/someperlscript.pl
done
Script perl itu sendiri secara internal memiliki pengamat folder / file yang dijalankan ketika file diubah di lokasi target.
Apakah ini ( while true
) ide yang bagus? Jika tidak, apa pendekatan yang lebih baik dan kuat?
TIA
EDIT: Karena ini tampaknya telah menghasilkan sedikit minat, inilah skenario lengkapnya. Script perl itu sendiri menonton direktori menggunakan pengamat file. Setelah menerima file baru (mereka tiba melalui rsync), ia mengambil yang baru dan memprosesnya. Sekarang file yang masuk mungkin rusak (jangan tanya .. berasal dari raspberry pi), dan terkadang prosesnya mungkin tidak dapat mengatasinya. Saya tidak tahu persis mengapa, karena kami belum mengetahui semua skenario.
TETAPI - jika prosesnya gagal karena beberapa alasan, kami ingin itu berjalan dan berjalan dan berurusan dengan file berikutnya, karena file berikutnya sama sekali tidak terkait dengan yang sebelumnya yang mungkin telah menyebabkan kesalahan.
Biasanya saya akan menggunakan semacam catch all dan membungkus seluruh kode di sekitarnya sehingga TIDAK PERNAH crash. Tetapi tidak yakin untuk perl.
Dari apa yang saya mengerti, menggunakan sesuatu seperti supervisor adalah pendekatan yang bagus untuk ini.
inotify
API sehingga Anda dapat menghindari lingkaran sibuk menunggu file untuk berubah di direktori target Anda.Jawaban:
Itu tergantung pada seberapa cepat script perl kembali. Jika kembali dengan cepat, Anda mungkin ingin memasukkan jeda kecil di antara eksekusi untuk menghindari beban CPU, misalnya:
Ini juga akan mencegah babi CPU jika skrip tidak ditemukan atau langsung crash.
Loop mungkin juga lebih baik diimplementasikan dalam skrip perl itu sendiri untuk menghindari masalah ini.
Edit:
Saat Anda menulis, tujuan loop hanya untuk memulai kembali skrip perl jika crash, pendekatan yang lebih baik adalah mengimplementasikannya sebagai layanan yang dipantau tetapi cara yang tepat untuk melakukannya tergantung pada OS. Contoh: Solaris smf, Linux systemd atau restarter berbasis cron.
sumber
while sleep 1; do ...
untuk menyimpan panggilan yang sebenarnya.until ! sleep 1; do ...; done
akan tetap menyimpan panggilan bawaan tersebut saat memulai skrip dengan segera.sleep 1& /someperlscript.pl; wait
.until
instruksi, saya telah membingungkannya dengando/until
loop hipotetis yang tidak ada di shell.Jawaban lain, tentang menggunakan
inotify
, benar, tetapi bukan jawaban untuk pertanyaan ini.Sebuah proses pengawas, seperti
supervisord
,upstart
, ataurunit
, dirancang untuk persis masalah menonton dan restart layanan jika crash.Distro Anda mungkin dilengkapi dengan pengawas proses bawaan.
sumber
while true
baik sebagai konstruksi "loop selamanya" tujuan umum. Seperti jawaban lain mengatakan, badan loop tidak boleh kosong, atau menjadi kosong berdasarkan perintah di dalam loop tidak berfungsi.Jika Anda menggunakan Linux, Anda mungkin ingin menggunakan perintah like
inotifywait
, yang membuatwhile
loop lebih sederhana:Di sini,
inotifywait
perintah akan duduk dan menunggu peristiwa sistem file terjadi (dalam contoh ini, ketika file dalam direktori ditulis ke). Pada titik itu, ia keluar dengan sukses dan tubuh loop dijalankan. Kemudian kembali menunggu lagi. Karenainotifywait
perintah menunggu sesuatu terjadi di direktori, itu jauh lebih efisien daripada terus-menerus polling direktori.sumber
Pindahkan sementara 1 ke skrip perl (Mengikuti saran @roaima)
sumber
Ketika skrip perl Anda dimaksudkan untuk terus berjalan sepanjang waktu, mengapa menggunakan konstruksi while? Ketika perl gagal karena beberapa masalah serius, skrip perl baru yang dimulai saat itu mungkin macet sama kerasnya. Lagi-dan-lagi-dan-seterusnya.
jika Anda benar-benar ingin perl Anda mulai lagi, pertimbangkan crontab dan skrip yang pertama memeriksa untuk menjalankan instance. Dengan cara ini skrip Anda bahkan akan dimulai setelah reboot.
sumber
Secara umum tidak ada masalah menggunakan
while true
karena ini adalah tes kecil yang hanya dieksekusi setelah skrip perl dihentikan. Perlu diingat bahwa tergantung pada varian Linux / Unix yang Anda gunakan, skrip mungkin akan dihentikan saat log off. Dalam kasus seperti itu pertimbangkan untuk menggunakan loop dalam skrip dan menyebutnya dengannohup
dan letakkan di latar belakang yaitunohup myscript &
Jika skrip perl berakhir terlalu sering dan menyebabkan beban CPU dari pada beban ini bertanggung jawab pada skrip perl dan bukan
while true
.Lihat juga
man nohup
untuk detailnya.sumber
Jika Anda ingin mengelola suatu proses, Anda mungkin ingin melihat ke manajer proses untuk melakukannya.
Dengan banyak sistem terbaru, Anda dapat menggunakan systemd untuk memantau proses Anda (yang merupakan salah satu manfaat dari systemd dibandingkan skrip init klasik). Jika distro pilihan Anda tidak menggunakan systemd, Anda bisa menggunakan daemontools atau monit .
sumber
mon
adalah alternatif sederhana, jika pelukan monit dan systemd mengganggu Anda sebanyak yang saya lakukan.The
while
loop benar-benar bukan ide yang baik. Tidak ada jalan keluar di sana - itu hanya berjalan selamanya - secara statis . Sejumlah hal dapat berubah di lingkungan dan tidak akan terpengaruh - dan ini bisa buruk.Sebagai contoh, jika shell executable yang bertanggung jawab untuk
while
loop itu ditingkatkan, kernel tidak akan dapat melepaskan ruang disk untuk versi lama sampai skrip itu berhenti karena itu perlu mempertahankan deskriptor selama itu berjalan. Dan itu berlaku untuk semua file yang mungkin dibuka oleh shell untuk alasan apa pun untuk menjalankan loop - semuanya akan terbuka olehwhile
loop ini selama dijalankan - selamanya.Dan jika, Tuhan melarang, ada kebocoran memori di mana saja di shell menjalankan loop itu - bahkan paling banyak - itu hanya akan terus bocor - secara statis . Itu akan dibangun tanpa pengawasan dan satu-satunya jalan adalah dengan membunuhnya dengan paksa, lalu memulainya hanya untuk melakukan hal yang sama nanti.
Ini sebenarnya bukan cara Anda harus menyiapkan proses latar belakang - setidaknya, tidak menurut saya. Sebaliknya, seperti yang saya pikirkan, harus ada titik reset - penyegaran skrip dan kondisinya. Cara termudah untuk melakukannya adalah dengan
exec
. Anda dapat mengganti proses saat ini dengan yang baru - sambil mempertahankan PID yang sama - tetapi masih menjalankan yang baru proses .Misalnya, jika
perl
skrip Anda harus mengembalikan true setelah berhasil menangani modifikasi file di beberapa direktori yang dipantau:...atau semacam itu. Sesuatu yang memungkinkan mesin dasar di belakang loop untuk menyegarkan sesekali.
sumber
Saya mengubah beberapa jawaban ini, tetapi secara naluriah saya memiliki perasaan paling hangat untuk jawaban @ WalterA. Yah, saya lakukan sampai saya membuat jawaban saya sendiri ...
Secara pribadi, saya cenderung memperbarui skrip Perl sehingga ia menulis entri log deskriptif tentang kegagalan dan mengirimkan peringatan ke administrator.
Jika skrip Perl dimaksudkan untuk terus berjalan, menunggu perubahan acara dari sistem file, mengapa gagal?
Jika tidak gagal, mengapa Anda khawatir tentang membungkusnya dalam skrip untuk memulai kembali tanpa batas?
Jika ada masalah konfigurasi atau ketergantungan yang rusak yang menyebabkan skrip Perl dibatalkan, cukup restart berulang-ulang tidak akan membuatnya tiba-tiba mulai berfungsi.
Anda tahu definisi kegilaan, bukan? (melakukan hal yang sama berulang-ulang, mengharapkan hasil yang berbeda). Hanya mengatakan. ;-)
sumber