Necesito instalar un programa como servicio en Red Hat. No se ejecuta en segundo plano, no administra su archivo PID ni administra sus propios registros. Simplemente se ejecuta e imprime en STDOUT y STDERR.
Utilizando los scripts de inicio estándar como guías, he desarrollado lo siguiente:
#!/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
Puede ser que mi error fue copiar y pegar y modificar algunos de los scripts existentes en /etc/init.d. En cualquier caso, el servicio resultante se comporta de manera extraña:
- cuando lo inicio con
service someprog startel programa se imprime en la terminal y el comando no se completa. - si CTRL-C, imprime "Sesión terminada, matando shell ... ... matado. FALLIDO". Tengo que hacer esto para recuperar mi indicador de shell nuevamente.
- ahora cuando ejecuto
service someprog statusdice que se está ejecutando y enumera su PID. Puedo verlopsasí que se está ejecutando. - ahora cuando corro
service someprog stopno se detiene. Puedo verificar que todavía se está ejecutandops.
¿Qué necesito cambiar para que someprogse envíe en segundo plano y se administre como un servicio?
Editar: ahora he encontrado un par de preguntas relacionadas, ninguna de las cuales tiene una respuesta real que no sea "hacer otra cosa":
- Call to daemon en un script /etc/init.d está bloqueando, no se ejecuta en segundo plano
- ¿Conseguir que el script de shell se ejecute como demonio en CentOS?
Editar: esta respuesta sobre doble bifurcación podría haber resuelto mi problema, pero ahora mi programa en sí mismo se bifurca y funciona: /programming//a/9646251/898699

Respuestas:
El comando "no se completa" porque la
daemonfunción no ejecuta su aplicación en segundo plano por usted. Deberá agregar un&al final de sudaemoncomando de la siguiente manera:daemon --user someproguser $exec &Si
someprogno se manejaSIGHUP, debe ejecutar el comandonohuppara asegurarse de que su proceso no reciba, loSIGHUPque le indica a su proceso que salga cuando salga el shell principal. Eso se vería así:daemon --user someproguser "nohup $exec" &En su
stopfunción,killproc "exec"no está haciendo nada para detener su programa. Debería leer así:killproc $execkillprocrequiere la ruta completa a su aplicación para detenerla correctamente. He tenido algunos problemaskillprocen el pasado, por lo que también puede matar el PID en el PIDFILE en el que debería escribirsomeprogel PID con algo como esto:cat $pidfile | xargs killPuede escribir el PIDFILE de esta manera:
ps aux | grep $exec | grep -v grep | tr -s " " | cut -d " " -f2 > $pidfiledonde
$pidfileapunta a/var/run/someprog.pid.Si desea [OK] o [FAILED] en su
stopfunción, debe usar las funcionessuccessyfailurede/etc/rc.d/init.d/functions. No necesita estos en lastartfunción porquedaemonllama al apropiado para usted.También solo necesita comillas alrededor de cadenas con espacios. Sin embargo, es una elección de estilo, así que depende de usted.
Todos estos cambios se ven así:
fuente
Si este es su programa, escríbalo como un demonio apropiado. Especialmente si es por redistribución. :)
Puedes probar monit . O tal vez algo como runit o daemontools. Esos poderosos no tienen paquetes fácilmente disponibles. Daemontools es de DJB, si eso influye en su decisión (en cualquier dirección).
fuente
He investigado un poco más y parece que la respuesta es "no puedes hacer eso". El programa que se debe ejecutar debe demonizarse correctamente: bifurca y separa sus controladores de archivo estándar, se desconecta del terminal y comienza una nueva sesión.
Editar: aparentemente estoy equivocado: doble bifurcación funcionaría. /programming//a/9646251/898699
fuente