Saya ingin daemonizer yang dapat mengubah skrip atau perintah umum yang berubah-ubah menjadi daemon .
Ada dua kasus umum yang ingin saya tangani:
Saya memiliki skrip yang harus berjalan selamanya. Jika pernah mati (atau saat reboot), mulai ulang. Jangan biarkan ada dua salinan yang berjalan sekaligus (deteksi jika salinan sudah berjalan dan jangan luncurkan dalam kasus itu).
Saya memiliki skrip sederhana atau perintah baris perintah yang ingin terus saya jalankan berulang kali selamanya (dengan jeda singkat di antara proses). Sekali lagi, jangan izinkan dua salinan skrip untuk dijalankan sekaligus.
Tentu saja sepele untuk menulis loop "while (true)" di sekitar skrip pada kasus 2 dan kemudian menerapkan solusi untuk kasus 1, tetapi solusi yang lebih umum hanya akan menyelesaikan kasus 2 secara langsung karena itu berlaku untuk skrip dalam kasus 1 sebagai baik (Anda mungkin hanya ingin jeda yang lebih pendek atau tidak ada jeda jika skrip tidak dimaksudkan untuk mati (tentu saja jika skrip benar - benar tidak pernah mati maka jeda sebenarnya tidak masalah)).
Perhatikan bahwa solusinya tidak boleh melibatkan, katakanlah, menambahkan kode penguncian file atau rekaman PID ke skrip yang ada.
Lebih khusus lagi, saya ingin program "daemonize" yang dapat saya jalankan
% daemonize myscript arg1 arg2
atau, misalnya,
% daemonize 'echo `date` >> /tmp/times.txt'
yang akan membuat daftar tanggal bertambah ditambahkan ke times.txt. (Perhatikan bahwa jika argumen untuk daemonize adalah skrip yang berjalan selamanya seperti pada kasus 1 di atas, maka daemonize akan tetap melakukan hal yang benar, memulai ulang bila perlu.) Saya kemudian dapat meletakkan perintah seperti di atas di .login saya dan / atau cron setiap jam atau menit (tergantung seberapa khawatir saya tentang hal itu meninggal secara tidak terduga).
NB: Skrip daemonize perlu mengingat string perintah yang di-daemonisasi sehingga jika string perintah yang sama di-daemonisasi lagi, salinan kedua tidak akan diluncurkan.
Selain itu, solusi idealnya harus berfungsi pada OS X dan linux tetapi solusi untuk satu atau yang lain dipersilakan.
EDIT: Tidak apa-apa jika Anda harus memintanya dengan sudo daemonize myscript myargs
.
(Jika saya memikirkan ini semua salah atau ada solusi parsial yang cepat dan kotor, saya ingin mendengarnya juga.)
PS: Jika bermanfaat, berikut pertanyaan serupa khusus untuk python.
Dan ini jawaban untuk pertanyaan serupa memiliki apa yang tampaknya menjadi idiom yang berguna untuk mengutuk cepat-dan-kotor dari skrip yang sewenang-wenang:
Jawaban:
Anda dapat membuat daemonisasi yang dapat dieksekusi di Unix dengan menggunakan nohup dan operator &:
Perintah nohup memungkinkan Anda untuk menutup sesi shell Anda tanpa mematikan skrip Anda, sementara & menempatkan skrip Anda di latar belakang sehingga Anda mendapatkan prompt shell untuk melanjutkan sesi Anda. Satu-satunya masalah kecil dengan ini adalah standar keluar dan kesalahan standar keduanya dikirim ke ./nohup.out, jadi jika Anda memulai beberapa skrip dalam manor ini, hasilnya akan saling terkait. Perintah yang lebih baik adalah:
Ini akan mengirimkan standar ke file pilihan Anda dan kesalahan standar ke file lain pilihan Anda. Jika Anda ingin menggunakan hanya satu file untuk standard out dan standard error, Anda dapat menggunakan ini:
2> & 1 memberi tahu shell untuk mengalihkan kesalahan standar (deskriptor file 2) ke file yang sama sebagai standar keluar (deskriptor file 1).
Untuk menjalankan perintah hanya sekali dan memulai ulang jika mati, Anda dapat menggunakan skrip ini:
Argumen pertama adalah nama file pid yang akan digunakan. Argumen kedua adalah perintah. Dan semua argumen lainnya adalah argumen perintah.
Jika Anda menamai skrip ini restart.sh ini adalah bagaimana Anda menyebutnya:
sumber
trap EXIT
)<
dalamtest
adalah perbandingan ASCII, bukan perbandingan bilangan bulat. Ini mungkin masih berfungsi, tetapi dapat menyebabkan bug.Saya minta maaf untuk jawaban yang panjang (silakan lihat komentar tentang bagaimana jawaban saya memenuhi spesifikasi). Saya mencoba untuk menjadi komprehensif, jadi Anda memiliki kaki sebaik mungkin. :-)
Jika Anda dapat menginstal program (memiliki akses root), dan bersedia melakukan kerja keras satu kali untuk menyiapkan skrip Anda untuk eksekusi daemon (yaitu, lebih terlibat daripada sekadar menentukan argumen baris perintah untuk dijalankan pada baris perintah, tetapi hanya perlu dilakukan sekali per layanan), saya memiliki cara yang lebih kuat.
Ini melibatkan penggunaan daemontools . Bagian selanjutnya dari posting ini menjelaskan cara menyiapkan layanan menggunakan daemontools.
Pengaturan awal
/service
. Penginstal seharusnya sudah melakukan ini, tetapi verifikasi saja, atau jika menginstal secara manual. Jika Anda tidak menyukai lokasi ini, Anda dapat mengubahnya disvscanboot
skrip Anda , meskipun sebagian besar pengguna daemontools biasa menggunakannya/service
dan akan bingung jika Anda tidak menggunakannya.init
(yaitu, tidak menggunakan/etc/inittab
), Anda perlu menggunakan pra-instalinittab
sebagai dasar untuk mengatursvscanboot
agar dipanggil olehinit
. Ini tidak sulit, tetapi Anda perlu tahu cara mengkonfigurasiinit
yang digunakan OS Anda.svscanboot
adalah skrip yang memanggilsvscan
, yang melakukan pekerjaan utama mencari layanan; itu dipanggil dariinit
sehinggainit
akan mengatur untuk memulai kembali jika mati karena alasan apa pun.Penyiapan per layanan
/var/lib/svscan
, tetapi lokasi baru mana pun akan baik-baik saja.Saya biasanya menggunakan skrip untuk menyiapkan direktori layanan, untuk menghemat banyak pekerjaan manual yang berulang. misalnya,
di mana
some-service-name
nama yang ingin Anda berikan layanan Anda,user
adalah pengguna untuk menjalankan layanan itu sebagai, danloguser
pengguna untuk menjalankan logger sebagai. (Logging dijelaskan sebentar lagi.)fghack
, meskipun ini ada untungnya : Anda tidak dapat lagi mengontrol program menggunakansvc
.run
skrip untuk memastikannya melakukan apa yang Anda inginkan. Anda mungkin perlusleep
menelepon di atas, jika Anda berharap layanan Anda sering keluar./service
mengarah ke direktori layanan Anda. (Jangan letakkan direktori layanan langsung di/service
dalamnya; akan lebih sulit untuk menghapus layanan darisvscan
jam tangan.)Logging
mkservice
);svscan
menangani pengiriman pesan log ke layanan logging.mkservice
akan membuat file log yang dirotasi otomatis dan diberi stempel waktu dilog/main
direktori. File log saat ini disebutcurrent
.tai64nlocal
akan menerjemahkan cap waktu ke dalam format yang dapat dibaca manusia. (TAI64N adalah stempel waktu atom 64-bit dengan hitungan nanodetik.)Mengontrol layanan
svstat
untuk mendapatkan status layanan. Perhatikan bahwa layanan logging bersifat independen, dan memiliki statusnya sendiri.svc
. Misalnya, untuk memulai ulang layanan Anda, gunakansvc -t /service/some-service-name
;-t
berarti "kirimSIGTERM
".-h
(SIGHUP
),-a
(SIGALRM
),-1
(SIGUSR1
),-2
(SIGUSR2
), dan-k
(SIGKILL
).-d
. Anda juga dapat mencegah layanan memulai secara otomatis saat boot dengan membuat file bernamadown
dalam direktori layanan.-u
. Ini tidak diperlukan kecuali Anda telah menurunkannya sebelumnya (atau mengaturnya untuk tidak memulai otomatis).-x
; biasanya digunakan dengan-d
untuk menghentikan layanan juga. Ini adalah cara biasa untuk mengizinkan layanan dihapus, tetapi Anda harus membatalkan tautan layanan dari/service
pertama, atausvscan
supervisor akan dimulai ulang. Selain itu, jika Anda membuat layanan dengan layanan logging (mkservice -l
), ingatlah untuk juga keluar dari supervisor logging (misalnyasvc -dx /var/lib/svscan/some-service-name/log
) sebelum menghapus direktori layanan.Ringkasan
Kelebihan:
init
disediakan.Kekurangan:
svc
, dan tidak dapat menjalankan skrip jalankan secara langsung (karena mereka tidak akan berada di bawah kendali supervisor).supervise
proses dalam tabel proses Anda.)Secara seimbang, menurut saya daemontools adalah sistem yang sangat baik untuk kebutuhan Anda. Saya menyambut semua pertanyaan tentang cara menyiapkan dan memeliharanya.
sumber
supervise
, pengawas, mengurus memulai kembali layanan apa pun yang keluar. Itu menunggu satu detik di antara restar; jika itu tidak cukup waktu untuk Anda, tidur di bagian atas skrip layanan dijalankan.supervise
didukung olehsvscan
, jadi jika supervisor meninggal, itu akan dimulai kembali. 2b.svscan
didukung olehinit
, yang akan memulai ulang secara otomatissvscan
jika diperlukan. 2c. Jika Andainit
mati karena alasan apa pun, Anda tetap kacau. :-Psvstat
dansvc
dapat dikerjakan oleh alat.Saya pikir Anda mungkin ingin mencoba
start-stop-daemon(8)
. Lihat skrip di/etc/init.d
distro Linux mana pun sebagai contoh. Itu dapat menemukan proses yang dimulai dengan perintah baris perintah atau file PID, sehingga cocok dengan semua kebutuhan Anda kecuali menjadi pengawas untuk skrip Anda. Tetapi Anda selalu dapat memulai skrip pengawas daemon lain yang hanya memulai ulang skrip Anda jika perlu.sumber
start-stop-daemon
ada, baik (mulai 10.9).start-stop-daemon
masih hidup dan aktif di Linux; tapi setelah membaca jawaban stackoverflow.com/a/525406/45375 saya menyadari bahwa OSX melakukan hal sendiri:launchd
.Anda harus melihat daemonize . Ini memungkinkan untuk mendeteksi salinan kedua (tetapi menggunakan mekanisme penguncian file). Juga bekerja pada distribusi UNIX dan Linux yang berbeda.
Jika Anda perlu menjalankan aplikasi Anda sebagai daemon secara otomatis, Anda perlu membuat skrip init yang sesuai.
Anda dapat menggunakan template berikut:
sumber
killproc
yang berhenti: jika Anda memiliki proses yang, katakanlah, berjalanjava
, itukillproc
akan menyebabkan semua proses Java lainnya dimatikan juga.$corelimit >/dev/null 2>&1 ; $*
Jadi saya ragu ini akan membuat daemonisasi apa pun ...Sebagai alternatif dari yang telah disebutkan
daemonize
dandaemontools
, ada perintah daemon dari paket libslack.daemon
cukup dapat dikonfigurasi dan tidak peduli dengan semua hal daemon yang membosankan seperti restart otomatis, logging atau penanganan pidfile.sumber
Jika Anda menggunakan OS X secara khusus, saya sarankan Anda melihat cara kerja launchd. Ini akan secara otomatis memeriksa untuk memastikan skrip Anda berjalan dan meluncurkannya kembali jika perlu. Ini juga mencakup semua jenis fitur penjadwalan, dll. Ini harus memenuhi persyaratan 1 dan 2.
Untuk memastikan hanya satu salinan skrip Anda yang dapat berjalan, Anda perlu menggunakan file PID. Umumnya saya menulis file ke /var/run/.pid yang berisi PID dari instance yang sedang berjalan. jika file tersebut ada saat program dijalankan, ia memeriksa apakah PID dalam file tersebut benar-benar berjalan (program mungkin macet atau lupa untuk menghapus file PID). Jika ya, batalkan. Jika tidak, mulai jalankan dan timpa file PID.
sumber
Daemontools ( http://cr.yp.to/daemontools.html ) adalah sekumpulan utilitas hard-core yang cukup digunakan untuk melakukan ini, ditulis oleh dj bernstein. Saya telah menggunakan ini dengan beberapa keberhasilan. Bagian yang mengganggu tentang itu adalah bahwa tidak ada skrip yang mengembalikan hasil yang terlihat saat Anda menjalankannya - hanya kode pengembalian yang tidak terlihat. Tapi begitu itu berjalan itu antipeluru.
sumber
Dapatkan pertama
createDaemon()
dari http://code.activestate.com/recipes/278731/Kemudian kode utamanya:
sumber
Ini adalah versi yang berfungsi lengkap dengan contoh yang dapat Anda salin ke direktori kosong dan coba (setelah menginstal dependensi CPAN, yaitu Getopt :: Long , File :: Spec , File :: Pid , dan IPC :: System: : Sederhana - semuanya sangat standar dan sangat disarankan untuk peretas mana pun: Anda dapat menginstal semuanya sekaligus dengan
cpan <modulename> <modulename> ...
).keepAlive.pl:
example.pl:
Sekarang Anda dapat menjalankan contoh di atas dengan:
./keepAlive.pl --pidfile=pidfile --command=./example.pl 1 2 3
dan filepidfile
akan dibuat, dan Anda akan melihat hasilnya:sumber
Anda juga dapat mencoba Monit . Monit adalah layanan yang memantau dan melaporkan layanan lain. Meskipun ini terutama digunakan sebagai cara untuk memberi tahu (melalui email dan sms) tentang masalah runtime, ini juga dapat melakukan apa yang disarankan oleh sebagian besar saran lain di sini. Itu dapat secara otomatis memulai dan menghentikan program, mengirim email, memulai skrip lain, dan memelihara log output yang dapat Anda ambil. Selain itu, saya merasa mudah untuk menginstal dan memelihara karena ada dokumentasi yang solid.
sumber
Anda dapat mencoba untuk abadi Ini adalah pengawas lintas platform * nix (OS agnostik).
Untuk mencoba cepat di macOS:
Jika Anda menggunakan FreeBSD dari port atau dengan menggunakan pkg:
Untuk Linux dengan mengunduh binari yang telah dikompilasi atau dari sumber: https://immortal.run/source/
Anda bisa menggunakannya seperti ini:
Atau dengan file YAML konfigurasi yang memberi Anda lebih banyak opsi, misalnya:
Jika Anda juga ingin menyimpan output kesalahan standar dalam file terpisah, Anda dapat menggunakan sesuatu seperti:
sumber
Saya telah melakukan serangkaian perbaikan pada jawaban lainnya .
sleep
)-h
eval
, sehingga Anda dapat membuat skrip shell apa pun sebagai string untuk dikirim ke skrip ini sebagai argumen terakhir (atau argumen tambahan) agar dapat melakukan daemonisasi-lt
alih - alih<
Berikut skripnya:
Pemakaian:
Berhati-hatilah jika Anda menjalankan skrip ini dari direktori yang berbeda, skrip ini mungkin menggunakan pidfile yang berbeda dan tidak mendeteksi instance yang sedang berjalan. Karena ini dirancang untuk menjalankan dan memulai kembali perintah sementara yang disediakan melalui argumen, tidak ada cara untuk mengetahui apakah sesuatu telah dimulai, karena siapa yang akan mengatakan apakah itu perintah yang sama atau tidak? Untuk meningkatkan penegakan ini yang hanya menjalankan satu contoh dari sesuatu, diperlukan solusi khusus untuk situasi tersebut.
Selain itu, agar berfungsi sebagai daemon yang tepat, Anda harus menggunakan (minimal) nohup sebagai jawaban lain yang menyebutkan. Saya tidak berusaha memberikan ketahanan apa pun terhadap sinyal yang mungkin diterima proses.
Satu hal lagi yang perlu diperhatikan adalah bahwa membunuh skrip ini (jika dipanggil dari skrip lain yang dimatikan, atau dengan sinyal) mungkin tidak berhasil membunuh anak tersebut, terutama jika anak itu adalah skrip lain . Saya tidak yakin mengapa ini terjadi, tetapi tampaknya ada sesuatu yang berhubungan dengan cara
eval
kerja, yang misterius bagi saya. Jadi mungkin bijaksana untuk mengganti baris itu dengan sesuatu yang hanya menerima satu perintah seperti di jawaban lain.sumber