Esegue il programma arbitrario come daemon da script init

Ho bisogno di installare un programma come servizio in Red Hat. Non è in background, gestisce il suo file PID o gestisce i propri registri. Funziona correttamente e printing su STDOUT e STDERR.

Utilizzando gli script init standard come guide, ho sviluppato quanto segue:

  • Installazione minima del server Red Hat
  • Creare un file solo se esiste la directory?
  • Velocità delle distro Linux differenti - perché la differenza?
  • Server multipli sullo stesso porto, utilizzando un bilanciatore di carico elastico
  • Configurazione di ppp per il supporto di IPv6
  • Anche se 80 e 443 sono porte di sistema, come sono in molti casi i server web in grado di legargli loro comunque?
  • #!/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 

    Potrebbe essere che il mio errore fosse quello di copiare-incollare e modificare alcuni degli script esistenti in /etc/init.d. In each caso, il servizio risultante si comport stranamente:

    • quando l'avvio con service someprog start il programma viene printingto al terminal e il command non viene completato.
    • se ho CTRL-C, stampe "Sessione terminata, uccidendo shell … … ucciso. FAILED". Devo farlo per get la mia richiesta di shell nuovamente.
    • ora quando service someprog status dice che è in esecuzione e elenca il suo PID. Posso vederlo in ps così è in esecuzione.
    • ora quando esegue il service someprog stop non riesce a smettere. Posso verificare che sia ancora in esecuzione con ps .

    Cosa devo cambiare in modo che someprog sia inviato allo background e gestito come un servizio?

    Modifica: ho trovato un paio di domande correlate, nessuna di esse con una risposta effettiva diversa da "fare altra cosa":

    • Chiamata a daemon in uno script /etc/init.d blocca, non viene eseguito in background
    • Ottenere lo script di shell per eseguire come demone su CentOS?

    Modifica: questa risposta sul doppio fork potrebbe aver risolto il mio problema, ma ora il mio programma è a double forchetta e funziona: https://stackoverflow.com/a/9646251/898699

  • Come riavviare il postgresql 8.4 su Debian Squeeze quando non sono definiti cluster?
  • Il servizio non parte da Centos durante l'avvio
  • C'è un modo per controllare l'accesso ai filesystem con systemd?
  • Perché c'è un file /etc/init.d/mysql su questa macchina Slackware? Come poteva essere arrivato?
  • Problema con lo script di avvio
  • Come faccio a eseguire manualmente un init.d di Debian, non all'avvio?
  • 3 Solutions collect form web for “Esegue il programma arbitrario come daemon da script init”

    Il command "non completa" perché la function daemon non eseguire l'applicazione in background per te. Dovrai aggiungere un & alla fine del tuo command daemon :

    daemon --user someproguser $exec &

    Se someprog non gestisce SIGHUP , è necessario eseguire il command con nohup per assicurarsi che il process non riceve SIGHUP che indica che il process si esce quando la shell padre esce. Sarebbe così simile:

    daemon --user someproguser "nohup $exec" &

    Nella function stop , killproc "exec" non sta facendo nulla per fermare il programma. Dovrebbe leggere così:

    killproc $exec

    killproc richiede il path completo alla tua applicazione per bloccarlo correttamente. Ho avuto qualche problema con killproc in passato, quindi puoi uccidere anche il PID nel PIDFILE che dovresti scrivere a PID di someprog con qualcosa di simile:

    cat $pidfile | xargs kill

    Puoi scrivere il PIDFILE come questo:

    ps aux | grep $exec | grep -v grep | tr -s " " | cut -d " " -f2 > $pidfile

    where $pidfile punta a $pidfile .

    Se si desidera che [OK] o [FAILED] nella function di stop , utilizzare le funzioni di success e di failure da /etc/rc.d/init.d/functions . Non è necessario questi nella function di start perché il daemon chiama quello appropriato per te.

    Hai anche bisogno di citazioni attorno a stringhe con spazi. È una scelta di stile, però, è a te.

    Tutti questi cambiamenti sembrano così:

     #!/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 pidfile=/var/run/$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 "nohup $exec" & RETVAL=$? if [ $RETVAL -eq 0 ]; then touch $lockfile ps aux | grep $exec | grep -v grep | tr -s " " | cut -d " " -f2 > $pidfile fi echo fi return $RETVAL } stop() { check echo -n $"Stopping $prog: " killproc $exec && cat $pidfile | kill RETVAL=$? if [ $RETVAL -eq 0 ]; then rm -f $lockfile rm -f $pidfile success; echo else failure; echo fi 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 

    Se questo è il tuo programma, scrivi come demone appropriato. Soprattutto se è per la ridistribuzione. 🙂

    Potresti provare il monit . O forse qualcosa di simile a runit o daemontools. Quelli potenti non hanno pacchetti immediatamente disponibili. Daemontools è da DJB, se questo influenza la tua decisione (in entrambe le direzioni).

    Ho fatto ulteriori ricerche e sembra che la risposta è "non puoi farlo". Il programma da eseguire deve effettivamente démonizzare se stesso: fork e staccare i file standard di file, staccarsi dal terminal e avviare una nuova session.

    Modifica: a quanto pare sono sbagliato – il doppio forchettone functionrebbe. https://stackoverflow.com/a/9646251/898699

    Suggerimenti per Linux e Windows Server, quali Ubuntu, Centos, Apache, Nginx, Debian e argomenti di rete.