"Richtige" Möglichkeit, Shell-Skript als Daemon auszuführen

20

Ich schreibe ein Shell-Skript , das ich beim Start als Daemon ausführen möchte, ohne externe Tools wie daemontools oder daemonize zu verwenden .


Linux Daemon Writing HOWTO

Laut Linux Daemon Writing HOWTO hat ein richtiger Daemon die folgenden Eigenschaften:

  • Gabeln aus dem übergeordneten Prozess
  • schließt alle Datei - Deskriptoren (dh stdin, stdout, stderr)
  • Öffnet Protokolle zum Schreiben (falls konfiguriert)
  • ändert das Arbeitsverzeichnis in ein dauerhaftes (normalerweise /)
  • setzt den Dateimodus Maske (umask)
  • Erstellt eine eindeutige Sitzungs-ID (SID)

Einführung dämonisieren

Die Einführung zu Daemonize geht noch weiter und besagt, dass ein typischer Daemon auch:

  • Trennt sich von seinem Steuerterminal (falls vorhanden) und ignoriert alle Terminal-Signale
  • trennt sich von seiner Prozessgruppe
  • Griffe SIGCLD

Wie würde ich in einem all dies tun sh, dashoder bashSkript mit gängigen Linux - Tool nur?

Das Skript sollte in der Lage sein, auf so vielen Distributionen wie möglich ohne zusätzliche Software zu laufen, obwohl Debian unser Hauptaugenmerk ist.


ANMERKUNG: Ich weiß, dass es im StackExchange- Netzwerk viele Antworten gibt, die die Verwendung von nohupoder empfehlen setsid, aber keine dieser Methoden erfüllt alle oben genannten Anforderungen.


EDIT: Die Manpage daemon (7) gibt auch einige Hinweise, obwohl es einige Unterschiede zwischen älteren SysVund neueren Daemons zu geben scheint systemd. Da die Kompatibilität mit einer Vielzahl von Distributionen wichtig ist, stellen Sie bitte sicher, dass die Antwort alle Unterschiede deutlich macht.


user339676
quelle
1
Die "richtige" Art, ein eigenes Shell-Skript zu erstellen, besteht darin, es selbst protokollieren zu lassen, eine Methode zum Starten als Daemon bereitzustellen usw. Solche daemonund jene anderen Dinge dienen zum Ausführen von beliebigen Shell-Skripten, ohne dass das Ausführen als vorgesehen ist ein Daemon. Da Sie der Autor sind und die vollständige Kontrolle darüber haben, wie das Skript geschrieben wird, müssen Sie es so einrichten, dass es nur über ein systemd unitfile- oder rc.d-Skript gestartet werden kann. Du hast "Proper" angegeben!
Rich

Antworten:

16

Mit systemd sollten Sie in der Lage sein, ein Skript als Dämon auszuführen, indem Sie eine einfache Einheit erstellen. Sie können viele verschiedene Optionen hinzufügen, dies ist jedoch so einfach wie möglich.

Angenommen, Sie haben ein Skript /usr/bin/mydaemon.

#!/bin/sh

while true; do
  date;
  sleep 60;
done

Sie legen eine Einheit an /etc/systemd/system/mydaemon.service.

[Unit]
Description=My daemon

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

[Install]
WantedBy=multi-user.target 

Um den Dämon zu starten, rennst du

systemctl start mydaemon.service 

Um beim Booten zu starten, aktivieren Sie es

systemctl enable mydaemon.service

Wenn auf einem systemd - basiertes System, das eine Mehrheit der Linux - Distributionen heute ist, ist dies nicht wirklich ein externes Tool. Das Negative wäre, dass es nicht überall funktioniert.

johnramsden
quelle
3
Während ich den systemd-Ansatz mag, sagte das OP "keine externen Tools". Es gibt Linux-Distributionen, die noch kein systemd haben oder bei denen Sie zwischen systemd und etwas anderem wählen können, z. B. OpenRC.
Cristian Ciupitu
5
Für Distributionen, die systemd verwenden, systemdist es nicht mehr ein "externes Werkzeug" als bash.
Alexander
7

Mir fehlt hier wahrscheinlich etwas; warum genau wäre das nicht nohupangebracht? Natürlich ist es nicht genug für sich , aber es scheint einfach zu ergänzen.

#!/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 &

Soweit ich das beurteilen kann:

  • die Ausgabe wird entsprechend umgeleitet (ggf. / dev / null verwenden)
  • Die Umask wird vererbt
  • stdin stirbt jedoch am Ende des übergeordneten Skripts
  • Das Skript daemon.sh wird an init(oder systemd) repariert.

Ich habe das starke Gefühl, das Offensichtliche zu verpassen. Downvote, aber bitte sag mir was es ist :-)

LSerni
quelle
2
Ich wollte etwas sehr ähnliches vorschlagen. Ich verwende die Umleitung nohupmit &und I / O, um mehrere Nicht- CDaemon-Dienstprogramme zu starten, möglicherweise mit der zusätzlichen Sicherheit, dass Ihr nohupBefehl in a eingeschlossen wird su -c "nohup ... &" -s /bin/bash systemUser, um den Daemon als nicht privilegierter Benutzer auszuführen.
111 ---
4

Der screenin den meisten Distributionen enthaltene Linux- Befehl kann ein Shell-Skript dämonisieren. Ich benutze es oft. Hier ist ein kurzes Beispiel zum Starten, Auflisten und Beenden einer getrennten Bildschirmsitzung ...

# 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
S. Haran
quelle
2
screendeamonisiert kein Shell-Skript. Es läuft nur in einem bestimmten Terminal und kann sich von diesem Terminal lösen (wie Tastatur vom PC abziehen), ohne die Sitzung zu beenden. Das Programm, das auf dem getrennten Terminal ausgeführt wird, wird also im Hintergrund ausgeführt. Deshalb - Passprogramm im Hintergrund trennen.
Yurij Goncharuk