A veces tenemos la necesidad de hacer que un programa se ejecute al iniciarse el ordenador para efectuar cualquier tarea que se nos ocurra, en este caso, y para que nos sirva como ejemplo práctico, ejecutar un bot que nos informe sobre la IP pública de nuestra red local. Podemos hacerlo con cron, de una forma tan simple como escribir en crontab la siguiente línea:
@reboot python /media/Data_2/Documentos/Jorge/Programas/Python/IP_Bot/IP_Bot.py
En este caso, el ordenador intentará ejecutar el programa IP_Bot.py, ubicado en la ruta /media/Data_2/Documentos/Jorge/Programas/Python/IP_Bot/ (sí, un poco enrevesada la ruta, pero así es como está en mi máquina).
Y si todo lo demás está bien, Linux iniciará nuestro programa durante el proceso de arranque. Sin embargo, montar nuestro programa como un servicio de systemd tiene la ventaja de poder monitorizar mejor el estado de funcionamiento de nuestro programa, así como reiniciarlo en el caso de que éste dejara de funcionar por el motivo que fuera.
Y para que systemd pueda ejecutar nuestro programa en el arranque, lo primero es decirle cómo queremos que se ejecute, con este pequeño archivo:
[Unit] Description=IP_Bot, bot de XMPP y gestor de offset horario para dispositivos MQTT After=network.target metronome.service mosquitto.service [Service] ExecStart=/media/Data_2/Documentos/Jorge/Programas/Python/IP_Bot/IP_Bot Restart=always [Install] WantedBy = multi-user.target
Este archivo debe ubicarse en la ruta /etc/systemd/system/, y contiene algunas condiciones bajo las cuales debe ejecutarse nuestro programa, como por ejemplo «After», donde le decimos que queremos que se ejecute tras haberse iniciado los servicios de red (network), el servicio metronome (que es el servidor de XMPP sobre el que funcionará el bot) y el servicio mosquitto, ya que este bot además emite a través del servidor MQTT el offset horario para mis microcontroladores caseros. Pero no hay que asustarse, porque en esta entrada no vamos a ver a fondo el programa, que a todos los efectos podría realizar cualquier tarea, aunque fuera algo tan simple como escribir la señal horaria en un archivo cada equis tiempo.
Con «ExecStart» le damos la ruta del archivo a ejecutar, que en este caso es un script de bash llamado «IP_Bot» que a su vez redirige a mi programa en python. Hay un motivo para esto, como veremos más adelante.
«Restart=always» le dice a systemd que debe reiniciar este servicio si se interrumpiera por cualquier motivo, de manera que siempre lo tendremos funcionando.
Con «WantedBy = multi-user.target» le decimos al ordenador en qué estado del inicio de la máquina queremos que se ejecute nuestro servicio.
Y hecho esto, vamos a preparar el script que hemos pedido a systemd que nos ejecute:
#!/bin/bash ### BEGIN INIT INFO # Provides: IP_Bot # Required-Start: $all # Required-Stop: # Default-Start: 2 3 4 5 # Default-Stop: # Short-Description: Bot XMPP y gestor de offset horario ### END INIT INFO cd /media/Data_2/Documentos/Jorge/Programas/Python/IP_Bot/ python3 IP_Bot.py > /dev/null
En las dos últimas líneas de este script cambiamos el directorio, y luego ejecutamos el programa en python que contiene el código del bot, que es «IP_Bot.py». En las líneas anteriores se especifican, además de una descripción del programa, los estados de inicio del ordenador en los que debe iniciarse.
cd /media/Data_2/Documentos/Jorge/Programas/Python/IP_Bot/ python3 IP_Bot.py > /dev/null
Una vez guardado el script de arranque de la aplicación, debemos darle permisos para que se ejecute como un programa, con:
sudo chmod +x IP_Bot
Ahora habilitamos el servicio:
sudo systemctl enable ip_bot.service
Y por último lo ponemos en marcha:
sudo systemctl start ip_bot.service
Para comprobar que el servicio se encuentra en funcionamiento, pedimos un «status» del mismo, con:
sudo systemctl status ip_bot.service
Lo que debería darnos una salida semejante a ésta:
El «active» en verde nos indica que el servicio está funcionando. Esto no evitaría que, de haber algún error en el programa (en este caso en el script de python «IP_Bot.py»), el servicio se detenga, aunque como expliqué más arriba, el servicio está configurado para reiniciarse en caso de un error.