Cómo crear y ejecutar nuevas unidades de servicio en Systemd mediante el script de shell


Hace unos días, me encontré con una distribución Centos 7 de 32 bits y sentí el deseo de probarla en una vieja máquina de 32 bits. Después de arrancar, me di cuenta de que tenía un error y estaba perdiendo la conexión de red, por lo que tenía que "activarla" manualmente cada vez que arrancaba. Entonces, la pregunta era ¿cómo podría configurar un script que hiciera este trabajo, ejecutándose cada vez que arranco mi máquina?

Bueno, esto es muy simple y le mostraré la forma de usar las unidades de servicio del sistema. Pero primero una pequeña introducción a las unidades de servicio.

En este artículo, voy a explicar qué es una "unidad de servicio" en systemd, qué tan fácil es crear y ejecutar una. Intentaré simplificar qué son los "objetivos", por qué los llamamos "conjuntos de unidades" y cuáles son sus "deseos". Finalmente, estamos aprovechando una unidad de servicio para ejecutar nuestro propio script después del procedimiento de arranque.

Es obvio que su computadora es útil debido a los servicios que ofrece y para tener esta funcionalidad, muchos servicios deben ser llamados a medida que la computadora arranca y alcanza diferentes niveles. Otros servicios están llamados a ejecutarse cuando la computadora alcanza, por ejemplo, el nivel de rescate (nivel de ejecución 0) y otros cuando alcanza el nivel multiusuario (nivel de ejecución 3). Puedes imaginar estos niveles como objetivos.

De manera simple, el objetivo es una colección de unidades de servicio. Si desea echar un vistazo a las unidades de servicio que se ejecutan en su nivel graphical.target, escriba:

# systemctl --type=service

Como puede ver, algunos servicios están activos y "ejecutándose" todo el tiempo, mientras que otros se ejecutan una sola vez y terminan (salen). Si desea verificar el estado de un servicio, escriba:

# systemctl status firewalld.service

Como puede ver, verifiqué el estado de firewalld.service (consejo: puede usar la función de autocompletar para el nombre del servicio). Me informa que el servicio firewalld se está ejecutando todo el tiempo y está habilitado.

Habilitado y deshabilitado significa que el servicio se cargará permanentemente o no, durante el próximo arranque, respectivamente. Por otro lado, iniciar y detener un servicio tiene la limitación de la sesión actual y no es permanente.

Por ejemplo, si escribe:

# systemctl stop firewalld.service
# systemctl status firewalld.service

Puede ver que firewalld.service está inactivo (muerto) pero aún está habilitado, lo que significa que durante el próximo arranque se cargará. Entonces, si queremos que un servicio se cargue durante el tiempo de arranque en el futuro, debemos habilitarlo. ¡Qué gran conclusión! Creemos uno, es fácil.

Si vas a la carpeta:

# cd /etc/systemd/system
# ls -l

Puede ver algunos archivos de enlace de servicios de unidad y algunos directorios de los "deseos" de un objetivo. Por ejemplo: lo que el destino multiusuario quiere cargar cuando el procedimiento de arranque alcanza su nivel, se enumera en el directorio con el nombre /etc/systemd/system/multi-user.target.wants/.

# ls multi-user.target.wants/

Como puede ver, no contiene solo servicios, sino también otros destinos que también son colecciones de servicios.

Hagamos una unidad de servicio con el nombre connection.service.

# vim connection.service

y escriba lo siguiente (presione “i” para el modo de inserción), guárdelo y salga (con “esc” y “: wq!” ):

[Unit]
Description = making network connection up
After = network.target

[Service]
ExecStart = /root/scripts/conup.sh

[Install]
WantedBy = multi-user.target

Para explicar lo anterior: hemos creado una unidad de tipo de servicio (también puede crear unidades de tipo de destino), lo hemos configurado para que se cargue después de la red.target (puede entender que el procedimiento de arranque llega a los objetivos con un definido order) y queremos que cada vez que el servicio comience a ejecutar un script bash con el nombre conup.sh que vamos a crear.

La diversión comienza con la última parte [instalar]. Dice que será buscado por “multi-user.target”. Entonces, si habilitamos nuestro servicio, se creará un enlace simbólico a ese servicio dentro de la carpeta multi-user.target.wants. ¿Entiendo? Y si lo deshabilitamos ese enlace se borrará. Tan sencillo.

Solo habilítalo y verifica:

# systemctl enable connection.service

nos informa que se ha creado el enlace simbólico en la carpeta multi-user.target.wants. Revisalo:

# ls multi-user.target.wants/

Como puede ver, "connection.service" está listo para el próximo arranque, pero primero debemos crear el archivo de script.

# cd /root
# mkdir scripts
# cd scripts
# vim conup.sh

Agregue la siguiente línea dentro de vim y guárdelo:

#!/bin/bash
nmcli connection up enp0s3

Por supuesto, si desea que su script ejecute otra cosa, puede escribir lo que quiera en lugar de la segunda línea.

Por ejemplo,

#!/bin/bash
touch /tmp/testbootfile

eso crearía un archivo dentro de la carpeta/tmp (solo para verificar que su servicio esté funcionando).

También debemos hacer que el script sea ejecutable:

# chmod +x conup.sh

Ahora estamos listos. Si no quiere esperar hasta el próximo arranque (ya está habilitado) podemos iniciar el servicio para la sesión actual escribiendo:

# systemctl start connection.service

¡Voila! ¡Mi conexión está funcionando!

Si ha elegido escribir el comando "touch/tmp/testbootfile" dentro del script, solo para verificar su funcionalidad, verá este archivo creado dentro de la carpeta/tmp.

Realmente espero ayudarlo a descubrir de qué se tratan los servicios, los deseos, los objetivos y los scripts en ejecución durante el arranque.