Saya perlu menginstal program sebagai layanan di Red Hat. Itu tidak latar belakang sendiri, mengelola file PID-nya, atau mengelola log sendiri. Ini hanya berjalan dan mencetak ke STDOUT dan STDERR.
Menggunakan skrip init standar sebagai panduan, saya telah mengembangkan yang berikut ini:
#!/bin/bash
#
# /etc/rc.d/init.d/someprog
#
# Starts the someprog daemon
#
# chkconfig: 345 80 20
# description: the someprog daemon
# processname: someprog
# config: /etc/someprog.conf
# Source function library.
. /etc/rc.d/init.d/functions
prog="someprog"
exec="/usr/local/bin/$prog"
[ -e "/etc/sysconfig/$prog" ] && . "/etc/sysconfig/$prog"
lockfile="/var/lock/subsys/$prog"
RETVAL=0
check() {
[ `id -u` = 0 ] || exit 4
test -x "$exec" || exit 5
}
start() {
check
if [ ! -f "$lockfile" ]; then
echo -n $"Starting $prog: "
daemon --user someproguser "$exec"
RETVAL=$?
[ $RETVAL -eq 0 ] && touch "$lockfile"
echo
fi
return $RETVAL
}
stop() {
check
echo -n $"Stopping $prog: "
killproc "exec"
RETVAL=$?
[ $RETVAL -eq 0 ] && rm -f "$lockfile"
echo
return $RETVAL
}
restart() {
stop
start
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
status)
status "$prog"
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|restart|status}"
RETVAL=2
esac
exit $RETVAL
Mungkin kesalahan saya adalah menyalin-menempel dan memodifikasi beberapa skrip yang ada di /etc/init.d. Bagaimanapun, layanan yang dihasilkan berperilaku aneh:
- ketika saya memulainya dengan
service someprog start
program mencetak ke terminal dan perintah tidak selesai. - jika saya CTRL-C, ia mencetak "Sesi diakhiri, membunuh shell ... ... terbunuh. GAGAL". Saya harus melakukan ini untuk mendapatkan prompt shell saya kembali lagi.
- sekarang ketika saya menjalankannya
service someprog status
mengatakan itu berjalan dan daftar PID-nya. Saya bisa melihatnya dips
jadi sedang berjalan. - sekarang ketika saya menjalankannya
service someprog stop
gagal berhenti. Saya dapat memverifikasi bahwa itu masih berjalanps
.
Apa yang perlu saya ubah agar someprog
dikirim ke latar belakang dan dikelola sebagai layanan?
Sunting: Saya sekarang telah menemukan beberapa pertanyaan terkait, tidak satu pun dari mereka dengan jawaban aktual selain "melakukan sesuatu yang lain":
- Panggilan ke daemon dalam skrip /etc/init.d sedang memblokir, tidak berjalan di latar belakang
- Membuat skrip shell dijalankan sebagai daemon di CentOS?
Sunting: jawaban tentang penjemputan-ganda ini mungkin telah memecahkan masalah saya, tetapi sekarang program saya sendiri bercabang dua dan berfungsi: https://stackoverflow.com/a/9646251/898699
Jawaban:
Perintah "tidak selesai" karena
daemon
fungsi tidak menjalankan aplikasi Anda di latar belakang untuk Anda. Anda perlu menambahkan sebuah&
di akhirdaemon
perintah Anda seperti:daemon --user someproguser $exec &
Jika
someprog
tidak menanganiSIGHUP
, Anda harus menjalankan perintah dengannohup
untuk memastikan bahwa proses Anda tidak akan menerimaSIGHUP
yang memberitahu proses Anda untuk keluar ketika shell induk keluar. Itu akan terlihat seperti ini:daemon --user someproguser "nohup $exec" &
Dalam
stop
fungsi Anda ,killproc "exec"
tidak melakukan apa pun untuk menghentikan program Anda. Seharusnya berbunyi seperti ini:killproc $exec
killproc
membutuhkan jalur lengkap ke aplikasi Anda untuk menghentikannya dengan benar. Saya pernah mengalami masalah dengankillproc
di masa lalu, jadi Anda juga dapat membunuh PID di PIDFILE yang seharusnya Anda tuliskansomeprog
PID dengan sesuatu seperti ini:cat $pidfile | xargs kill
Anda dapat menulis PIDFILE seperti ini:
ps aux | grep $exec | grep -v grep | tr -s " " | cut -d " " -f2 > $pidfile
di mana
$pidfile
menunjuk ke/var/run/someprog.pid
.Jika Anda ingin [OK] atau [GAGAL] pada
stop
fungsi Anda, Anda harus menggunakansuccess
danfailure
fungsi dari/etc/rc.d/init.d/functions
. Anda tidak memerlukan ini dalamstart
fungsi karenadaemon
memanggil yang sesuai untuk Anda.Anda juga hanya perlu kutipan di sekitar string dengan spasi. Ini pilihan gaya, jadi terserah Anda.
Semua perubahan ini terlihat seperti ini:
sumber
Jika ini adalah program Anda, silakan tulis sebagai dasmon yang tepat. Terutama jika untuk redistribusi. :)
Anda dapat mencoba monit . Atau mungkin sesuatu seperti runit atau daemontools. Paket-paket besar itu mungkin belum tersedia. Daemontools berasal dari DJB, jika itu memengaruhi keputusan Anda (ke arah mana pun.)
sumber
Saya telah melakukan penelitian lebih lanjut dan tampaknya jawabannya adalah "Anda tidak bisa melakukan itu." Program yang akan dijalankan harus benar-benar daemonisasi sendiri dengan benar: garpu dan lepaskan filehandles standarnya, lepaskan dari terminal, dan mulai sesi baru.
Sunting: rupanya saya salah - forking ganda akan berhasil. https://stackoverflow.com/a/9646251/898699
sumber