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 start
el 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 status
dice que se está ejecutando y enumera su PID. Puedo verlops
así que se está ejecutando. - ahora cuando corro
service someprog stop
no se detiene. Puedo verificar que todavía se está ejecutandops
.
¿Qué necesito cambiar para que someprog
se 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
daemon
función no ejecuta su aplicación en segundo plano por usted. Deberá agregar un&
al final de sudaemon
comando de la siguiente manera:daemon --user someproguser $exec &
Si
someprog
no se manejaSIGHUP
, debe ejecutar el comandonohup
para asegurarse de que su proceso no reciba, loSIGHUP
que le indica a su proceso que salga cuando salga el shell principal. Eso se vería así:daemon --user someproguser "nohup $exec" &
En su
stop
función,killproc "exec"
no está haciendo nada para detener su programa. Debería leer así:killproc $exec
killproc
requiere la ruta completa a su aplicación para detenerla correctamente. He tenido algunos problemaskillproc
en el pasado, por lo que también puede matar el PID en el PIDFILE en el que debería escribirsomeprog
el PID con algo como esto:cat $pidfile | xargs kill
Puede escribir el PIDFILE de esta manera:
ps aux | grep $exec | grep -v grep | tr -s " " | cut -d " " -f2 > $pidfile
donde
$pidfile
apunta a/var/run/someprog.pid
.Si desea [OK] o [FAILED] en su
stop
función, debe usar las funcionessuccess
yfailure
de/etc/rc.d/init.d/functions
. No necesita estos en lastart
función porquedaemon
llama 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