„Właściwy” sposób uruchamiania skryptu powłoki jako demona

20

Piszę skrypt powłoki , który chciałbym uruchamiać jako demon podczas uruchamiania bez użycia zewnętrznych narzędzi, takich jak daemontools lub demonizuj .


Linux Daemon Writing HOWTO

Według HOWTO Daemon pisania , o właściwej demon ma następujące cechy:

  • widelce z procesu nadrzędnego
  • zamyka wszystkie deskryptory plików (czyli stdin, stdout, stderr)
  • otwiera dzienniki do zapisu (jeśli skonfigurowano)
  • zmienia katalog roboczy na trwały (zwykle /)
  • resetuje maskę trybu pliku (umask)
  • tworzy unikalny identyfikator sesji (SID)

demonizuj Wprowadzenie

Daemonize Wprowadzenie idzie dalej, stwierdzając, że to typowy demon również:

  • odłącza się od terminala sterującego (jeśli taki istnieje) i ignoruje wszystkie sygnały terminala
  • odłącza się od swojej grupy procesów
  • uchwyty SIGCLD

Jak bym to wszystko zrobić w sposób sh, dashlub bashskrypt tylko wspólnych narzędzi Linux?

Skrypt powinien być w stanie działać na możliwie największej liczbie dystrybucji bez dodatkowego oprogramowania, chociaż naszym głównym celem jest Debian .


UWAGA: Wiem, że w sieci StackExchange jest wiele odpowiedzi zalecających użycie nohuplub setsid, ale żadna z tych metod nie spełnia wszystkich powyższych wymagań.


EDYCJA: Strona podręcznika demona (7) również daje pewne wskazówki, chociaż wydaje się, że istnieją pewne różnice między SysVdemonami w starszym stylu i nowszymi systemd. Ponieważ ważna jest zgodność z różnymi dystrybucjami, upewnij się, że odpowiedź wyjaśnia wszelkie różnice.


użytkownik339676
źródło
1
„Właściwy” sposób na stworzenie własnego skryptu powłoki polega na zmuszeniu go do samodzielnego logowania, dostarczenia metody uruchamiania go jako demona itp. Rzeczy takie jak daemonte i inne służą do uruchamiania dowolnych skryptów powłoki bez możliwości działania jako demon. Ponieważ jesteś autorem i masz pełną kontrolę nad sposobem pisania tego skryptu, spraw, aby można go było uruchomić ze skryptu systemfile lub skryptu rc.d. Państwo było określić „Właściwa”!
Bogaty

Odpowiedzi:

16

Używając systemd powinieneś być w stanie uruchomić skrypt jako demon, tworząc prostą jednostkę. Istnieje wiele różnych opcji, które można dodać, ale jest to tak proste, jak to tylko możliwe.

Powiedz, że masz skrypt /usr/bin/mydaemon.

#!/bin/sh

while true; do
  date;
  sleep 60;
done

Tworzysz jednostkę /etc/systemd/system/mydaemon.service.

[Unit]
Description=My daemon

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

[Install]
WantedBy=multi-user.target 

Aby uruchomić demona, biegniesz

systemctl start mydaemon.service 

Aby rozpocząć przy rozruchu, włącz go

systemctl enable mydaemon.service

Jeśli w systemie opartym na systemie, którym jest większość dystrybucji Linuksa, to tak naprawdę nie jest to narzędzie zewnętrzne. Negatywne byłoby to, że nie wszędzie to zadziała.

johnramsden
źródło
3
Chociaż podoba mi się podejście systemowe, PO powiedział „brak narzędzi zewnętrznych”. Istnieją dystrybucje Linuksa, które nie mają jeszcze systemd lub pozwalają na wybór pomiędzy systemd a czymś innym, np. OpenRC.
Cristian Ciupitu,
5
W przypadku dystrybucji używających systemd systemdnie jest bardziej „narzędziem zewnętrznym” niż bash.
Alexander
7

Prawdopodobnie coś mi tu brakuje; dlaczego dokładnie nie nohupbyłoby właściwe? Oczywiście nie wystarczy sam , ale uzupełnienie wydaje się proste.

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

O ile widzę:

  • dane wyjściowe są odpowiednio przekierowane (w razie potrzeby użyj / dev / null)
  • umask jest dziedziczony
  • stdin umiera jednak na końcu skryptu nadrzędnego
  • skrypt daemon.sh jest ponownie przypisany do init(lub systemd)

Mam silne przeczucie, że tęsknię za oczywistością. Głosuj, ale powiedz mi, co to jest :-)

LSerni
źródło
2
Już miałem zaproponować coś bardzo podobnego. Używam nohupz &przekierowaniem I / O, aby uruchomić kilka Cnarzędzi nie będących demonami, być może z dodatkowym zabezpieczeniem polegającym na owijaniu nohuppolecenia wewnątrz a, su -c "nohup ... &" -s /bin/bash systemUseraby uruchomić demona jako użytkownik nieuprzywilejowany.
111 ---
4

Polecenie Linux screenzawarte w większości dystrybucji może demonizować skrypt powłoki. Często go używam. Oto szybki przykład, aby rozpocząć, wyświetlić listę i zakończyć sesję z odłączonym ekranem ...

# 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
źródło
2
screennie demonizuje skryptu powłoki. Po prostu działają w wyróżniającym się terminalu i mogą odłączyć się od tego terminala (np. Odłączyć klawiaturę od komputera) bez zamykania sesji. Tak więc program działający w odłączonym terminalu działa w tle. Dlatego - odłącz program pass w tle.
Yurij Goncharuk