Forma "adecuada" de ejecutar el script de shell como demonio


20

Estoy escribiendo un script de shell que me gustaría ejecutar como demonio en el inicio sin usar herramientas externas como daemontools o daemonize .


COMO de Linux Daemon Writing

De acuerdo con el Linux Daemon Writing HOWTO , un demonio adecuado tiene las siguientes características:

  • horquillas del proceso padre
  • cierra todos los descriptores de archivos (es decir, stdin, stdout, stderr)
  • abre registros para escribir (si está configurado)
  • cambia el directorio de trabajo a uno que sea persistente (generalmente /)
  • restablece la máscara de modo de archivo (umask)
  • crea una ID de sesión (SID) única

daemonize Introducción

La Introducción daemonize va más allá, afirmando que un demonio típico también:

  • se disocia de su terminal de control (si hay uno) e ignora todas las señales de terminal
  • se disocia de su grupo de procesos
  • manejas SIGCLD

¿Cómo voy a hacer todo esto en una sh, dasho bashla escritura con sólo herramientas comunes de Linux?

El script debería poder ejecutarse en tantas distribuciones como sea posible sin software adicional, aunque Debian es nuestro enfoque principal.


NOTA: Sé que hay muchas respuestas en la red de StackExchange que recomiendan el uso de nohupo setsid, pero ninguno de estos métodos aborda todos los requisitos anteriores.


EDITAR: La página de manual de daemon (7) también ofrece algunos consejos, aunque parece haber algunas diferencias entre los SysVdemonios de estilo antiguo y los systemdmás nuevos . Dado que la compatibilidad con una variedad de distribuciones es importante, asegúrese de que la respuesta aclare cualquier diferencia.



1
La forma "adecuada" de crear su propio script de shell es hacer que haga su propio registro, proporcionar un método para lanzarlo como un demonio, etc. Cosas como daemony esas otras cosas son para ejecutar scripts de shell arbitrarios sin ninguna disposición para ejecutarse como Un demonio. Como usted es el autor y tiene el control total de cómo se escribe ese script, hágalo para que pueda iniciarse desde un archivo systemd unitf o script rc.d. Usted hizo especifica "correcto"!
Rico

Respuestas:


16

Con systemd , debería poder ejecutar un script como demonio creando una unidad simple. Puede agregar muchas opciones diferentes , pero esto es lo más simple que puede obtener.

Digamos que tienes un guión /usr/bin/mydaemon.

#!/bin/sh

while true; do
  date;
  sleep 60;
done

Creas una unidad /etc/systemd/system/mydaemon.service.

[Unit]
Description=My daemon

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

[Install]
WantedBy=multi-user.target 

Para iniciar el demonio que corres

systemctl start mydaemon.service 

Para comenzar en el arranque lo habilitas

systemctl enable mydaemon.service

Si en un sistema basado en systemd, que es la mayoría de las distribuciones de Linux en la actualidad, esta no es realmente una herramienta externa. Sin embargo, lo negativo sería que no funcionará en todas partes.


3
Si bien me gusta el enfoque systemd, el OP dijo "no hay herramientas externas". Hay distribuciones de Linux que aún no tienen systemd, o le permiten usar elegir entre systemd y algo más, por ejemplo, OpenRC.
Cristian Ciupitu

55
Para las distribuciones que usan systemd, systemdno es más una "herramienta externa" que bash.
Alexander

7

Probablemente estoy perdiendo algo aquí; ¿Por qué exactamente no nohupsería apropiado? Por supuesto que no es suficiente solo , pero completándola parece sencillo.

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

Por lo que puedo ver:

  • la salida está apropiadamente redirigido (uso / dev / null si es necesario)
  • el umask es heredado
  • stdin sin embargo, muere al final del script principal
  • el script daemon.sh se reparented a init(o systemd)

Tengo la fuerte sensación de que me falta lo obvio. Voto negativo, pero por favor dime qué es :-)


2
Estaba a punto de sugerir algo muy similar. Yo uso nohupcon &E / S y redirección a lanzar varios no - Cutilidades demonio tal vez con la seguridad añadida de envolver su nohupinterior el mando de una su -c "nohup ... &" -s /bin/bash systemUserde ejecutar el demonio como un usuario sin privilegios.
111 ---

4

El screencomando de Linux contenido en la mayoría de las distribuciones puede demonizar un script de shell. Lo uso a menudo Aquí hay un ejemplo rápido para comenzar, enumerar y salir de una sesión de pantalla separada ...

# 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
screenno desamoniza el script de shell. Simplemente los ejecuta en un terminal distinguido y puede desconectarse de este terminal (como desconectar el teclado de la PC) sin cerrar la sesión. Entonces, el programa que se ejecuta en un terminal separado se ejecuta en segundo plano. Por lo tanto, separe el programa de pase en segundo plano.
Yurij Goncharuk
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.