El servicio Debian no inicia el archivo correctamente al iniciar

El servicio Debian no inicia el archivo correctamente al iniciar

Tengo un archivo llamado botstart.servicecon /etc/systemd/systemeste contenido:

[Unit]
Description=Start all discord bots (AntiSpam, AutoChat, Nyoko, Helper) and the lavalink server.

[Service]
ExecStart=/bin/bash /home/scripts/start.sh

[Install]
WantedBy=multi-user.target

Lo comencé systemctl enable botstart y decía que estaba habilitado. Reinicié mi VPS, pero el script no se ejecutó. Lo hice systemctl status botstarty me mostró esto:

root@Hetzner-01:~# systemctl status botstart
● botstart.service - Start all discord bots (AntiSpam, AutoChat, Nyoko, Helper)
   Loaded: loaded (/etc/systemd/system/botstart.service; enabled; vendor preset:
   Active: inactive (dead) since Wed 2021-10-27 01:37:10 CEST; 50s ago
  Process: 481 ExecStart=/bin/bash /home/scripts/start.sh (code=eited, status=0
 Main PID: 481 (code=existed, status=0/SUCCESS)

Oct 27 01:37:07 Hetzner-01 systemd[1]: STarted Start all discord bots (antiSpam,
Oct 27 01:37:10 Hetzner-01 bash[481]: Started all bots
Oct 27 01:37:10 Hetzner-01 systemd[1]: botstart.service: Succeeded.
lines 1-9/9 (END)...skipping...
● botstart.service - Start all discord bots (AntiSpam, AutoChat, Nyoko, Helper) and the lavalink server.
   Loaded: loaded (/etc/systemd/system/botstart.service; enabled; vendor preset: enabled)
   Active: inactive (dead) since Wed 2021-10-27 01:37:10 CEST; 50s ago
  Process: 481 ExecStart=/bin/bash /home/scripts/start.sh (code=eited, status=0/SUCCESS)
 Main PID: 481 (code=existed, status=0/SUCCESS)

Si ejecuto el script manualmente, funciona, pero de alguna manera no como un servicio, pero el servicio se ejecuta y el script se ejecuta (eso es lo que me dice el estado del servicio). ¿Alguien sabe por qué? Este es el código del script:

screen -dmS antispam bash -c "cd /home/AntiSpam; python3.8 main.py"
screen -dmS autochat bash -c "cd /home/AutoChat; python3.8 main.py"
screen -dmS helper bash -c "cd /home/Helper; python3.8 main.py"
screen -dmS lavalink bash -c "cd /home/Lavalink; python3.8 main.py"
sleep 3
screen -dmS nyoko bash -c "cd /home/Nyoko; python3.8 main.py"
echo "Started all bots"

Respuesta1

En su [Service]sección, no definió explícitamente un archivo Type=. Esto significa que por defecto será Type=simple.

La página de manual dice:

Si se configura en simple, el administrador de servicios considerará que la unidad se inició inmediatamente después de que se haya bifurcado el proceso de servicio principal. Se espera que el proceso configurado con ExecStart= sea el proceso principal del servicio....

En resumen, su guión es el proceso principal. Inicia una serie de procesos y luego sale. systemdve que su proceso principal sale y luego procede a limpiar los procesos secundarios que ya no tienen un padre.

En lugar de eso quieres Type=forking.

Si se configura en bifurcación, se espera que el proceso configurado con ExecStart= llame a fork() como parte de su inicio. Se espera que el proceso principal finalice cuando se complete el inicio y se configuren todos los canales de comunicación. El hijo continúa ejecutándose como el proceso de servicio principal y el administrador de servicios considerará que la unidad se inició cuando el proceso padre salga. Este es el comportamiento de los servicios tradicionales de UNIX. Si se utiliza esta configuración, se recomienda usar también la opción PIDFile=, para que systemd pueda identificar de manera confiable el proceso principal del servicio.

En este caso, se permitirá que sus procesos secundarios sigan vivos, incluso después de que finalice su script. Si agrega Type=forking, las cosas deberían funcionar mejor para usted.


Tenga en cuenta que existen otros problemas con su diseño. Si el único cambio que realiza es Type=forking, todavía tiene algunos problemas:

  • Si uno de los procesos finaliza, systemd puede decidir o no cuál es el MainPID y considerar todo su servicio inactive (dead). Escribir en a PIDFile=puede ayudar con esto, pero sospecho que no pretende que ninguno de estos procesos sea el MainPID.
  • Si un proceso falla, systemdno se puede informar un estado fallido. No está claro qué debería pasar con los otros procesos.

Recomendación 1: dividir cada proceso en su propio servicio. Entonces Type=simplefuncionará. De esta manera, si un servicio falla, puedes detectarlo y operarlo de manera confiable sin afectar a los otros bots.

Recomendación 2: Agregar Restart=on-failure. Esto permitirá que un servicio fallido se reinicie automáticamente (no se requiere intervención humana).

Recomendación 3: No llames basha quién screenllama python3. Simplemente llame a Python directamente. screenes una solución alternativa que no es necesaria en un systemdentorno.

Recomendación 4: Para implementar eso sleep 3, puedes usar unExecStartPre=

Siguiendo estas recomendaciones, nyoko.servicequedaría así:

[Unit]
Description=Nyoko discord bot

[Service]
WorkingDirectory=/home/Nyoko
ExecStartPre=/usr/bin/sleep 3
ExecStart=/usr/bin/python3 /home/Nyoko/main.py
Restart=on-failure

[Install]
WantedBy=multi-user.target

Recomendación 5: sleepno es demasiado fiable. En un buen día, pierde 3 segundos. En un mal día, no es suficiente y tu servicio fallará. Considere agregar After=lavalink.servicea su [Unit]sección para asegurarse lavalink.servicede que se inicie antes que algo que dependa de ello. Si lavalinktiene algún tipo de señal que muestra que se inició (se crea el archivo o se abre el socket), entonces puede activarlo.

información relacionada