Modo "corretto" per eseguire lo script di shell come demone


20

Sto scrivendo uno script di shell che vorrei eseguire come demone all'avvio senza utilizzare strumenti esterni come daemontools o daemonize .


Demone Linux che scrive HOWTO

Secondo il Linux Daemon Writing HOWTO , un demone corretto ha le seguenti caratteristiche:

  • forcelle dal processo genitore
  • chiude tutti i descrittori di file (cioè stdin, stdout, stderr)
  • apre i registri per la scrittura (se configurato)
  • cambia la directory di lavoro in una persistente (di solito /)
  • ripristina la maschera della modalità file (umask)
  • crea un ID sessione univoco (SID)

daemonize Introduzione

L' introduzione daemonize va oltre, affermando che un demone tipico anche:

  • si dissocia dal suo terminale di controllo (se presente) e ignora tutti i segnali del terminale
  • si dissocia dal suo gruppo di processo
  • maniglie SIGCLD

Come faccio a fare tutto questo in una sh, dasho bashscript con soli strumenti comuni di Linux?

Lo script dovrebbe essere in grado di funzionare su quante più distribuzioni possibile senza software aggiuntivo, sebbene Debian sia il nostro obiettivo principale.


NOTA: so che ci sono molte risposte sulla rete StackExchange che consiglia l'uso di nohupo setsid, ma nessuno di questi metodi risponde a tutti i requisiti di cui sopra.


EDIT: La manpage daemon (7) fornisce anche alcuni suggerimenti, anche se sembrano esserci alcune differenze tra i SysVdemoni di vecchio stile e systemdquelli più recenti. Poiché la compatibilità con una varietà di distro è importante, assicurarsi che la risposta chiarisca eventuali differenze.



1
Il modo "corretto" per creare il proprio script di shell è quello di farlo fare il proprio logging, fornire un metodo per avviarlo come demone, ecc. Cose come daemone quelle altre cose sono per eseguire script di shell arbitrari senza alcuna disposizione un demone. Dato che sei l'autore, in pieno controllo di come viene scritto quello script, fallo in modo che possa essere avviato solo da un file systemd o da uno script rc.d. Si hai specificato "corretta"!
Ricco

Risposte:


16

Usando systemd dovresti essere in grado di eseguire uno script come demone creando una semplice unità. Ci sono molte diverse opzioni che puoi aggiungere, ma è più semplice che puoi ottenere.

Di 'che hai una sceneggiatura /usr/bin/mydaemon.

#!/bin/sh

while true; do
  date;
  sleep 60;
done

Si crea un'unità /etc/systemd/system/mydaemon.service.

[Unit]
Description=My daemon

[Service]
ExecStart=/usr/bin/mydaemon
Restart=on-failure

[Install]
WantedBy=multi-user.target 

Per avviare il demone che corri

systemctl start mydaemon.service 

Per iniziare all'avvio lo si abilita

systemctl enable mydaemon.service

Se su un sistema basato su systemd, che oggi è la maggior parte delle distribuzioni Linux, questo non è davvero uno strumento esterno. Il negativo sarebbe che non funzionerà dappertutto però.


3
Mentre mi piace l'approccio systemd, l'OP ha detto "nessun strumento esterno". Esistono distribuzioni Linux che non hanno ancora systemd o che consentono di scegliere tra systemd e qualcos'altro, ad esempio OpenRC.
Cristian Ciupitu,

5
Per le distro che usano systemd, systemdnon è più uno "strumento esterno" di bash.
Alexander

7

Probabilmente mi manca qualcosa qui; perché esattamente non nohupsarebbe appropriato? Ovviamente non è abbastanza da solo , ma integrarlo sembra semplice.

#!/bin/bash

if [ "$1" = "DAEMON" ]; then
    # is this necessary? Add other signals at will (TTIN TTOU INT STOP TSTP)
    trap '' INT
    cd /tmp
    shift
    ### daemonized section ######
    for i in $( seq 1 10 ); do
        date
        sleep 5
    done
    #### end of daemonized section ####
    exit 0
fi

export PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin
umask 022
# You can add nice and ionice before nohup but they might not be installed
nohup setsid $0 DAEMON $* 2>/var/log/mydaemon.err >/var/log/mydaemon.log &

Per quanto posso vedere:

  • l'output viene reindirizzato in modo appropriato (utilizzare / dev / null se necessario)
  • l'umask è ereditata
  • stdin muore alla fine della sceneggiatura principale
  • lo script daemon.sh viene riparato in init(o systemd)

Ho la netta sensazione che mi manchi l'ovvio. Downvote, ma per favore dimmi di cosa si tratta :-)


2
Stavo per suggerire qualcosa di molto simile. Io uso nohupcon &e redirezione I / O di lanciare diversi non - Cutilità demone con forse la maggiore sicurezza di avvolgere il vostro nohupcomando all'interno di una su -c "nohup ... &" -s /bin/bash systemUserper eseguire il demone come utente non privilegiato.
111 ---

4

Il screencomando Linux contenuto nella maggior parte delle distro può demonizzare uno script di shell. Lo uso spesso. Ecco un breve esempio per avviare, elencare ed uscire da una sessione di schermo separata ...

# screen -dmS Session_Name  bash -c "while true; do date; sleep 60; done"

# screen -ls
There are screens on:
        8534.Session_Name       (04/04/2018 08:46:27 PM)        (Detached)

# screen -S Session_Name -X quit

2
screennon deamonizza lo script della shell. Li esegue semplicemente in un terminale distinto e può staccarsi da questo terminale (come scollegare la tastiera dal PC) senza chiudere la sessione. Pertanto, il programma in esecuzione in un terminale separato è in esecuzione in background. Pertanto - scollegare il programma di passaggio in background.
Yurij Goncharuk,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.