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:

  • Linux /etc/init.d - collegamento symlink, hard link o file effettivo?
  • C'è un modo per monitorare / dev / random?
  • ACL su Sci Linux 6 ext4 non si comport come penso che dovrebbero
  • Che cosa esattamente fare - il limite 1 / s e - il limite-burst significa nelle regole di iptables?
  • Installare APC RedHat
  • Come eseguire una sequenza di arresto e avvio adeguato dei servizi web con systemd?
  • #!/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

  • Fornitura di utenti normali (non root) con funzionalità di esecuzione automatica di initialization e arresto
  • mettendo lo script di shell sotto il controllo systemd
  • Come trovare i messaggi di errore dai file di init.d / rc.d di Linux?
  • process startpar lasciato appeso quando si iniziano i processi da rc.local o init.d
  • Avvio di un demone PHP da uno script init LSB w / start-stop-daemon
  • Init script & il verde
  • 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.