Idealmente esta tarea también se puede hacer usando cron, pero ya que tenemos systemd por qué debemos depender de tareas cron.
Usando OnBootSec= u OnStartupSec= podemos ejecutar fácilmente el script después de N minutos de arranque basado en el valor de N. Vamos a verificar esto usando algunos ejemplos:
Acerca de systemd.timer
- Un archivo de configuración de unidades cuyo nombre termina en “.timer” codifica información sobre un temporizador controlado y supervisado por systemd.
- Los elementos de configuración comunes se configuran en las secciones genéricas “[Unit]” e “[Install]”. Las opciones de configuración específicas del temporizador se configuran en la sección “[Timer]”.
- Para cada archivo de temporizador, debe existir un archivo de unidad correspondiente, que describa la unidad que se activará cuando transcurra el temporizador.
- Por omisión, se activa un servicio con el mismo nombre que el temporizador (excepto el sufijo). Ejemplo: un archivo de temporizador algo.timer activa un servicio coincidente algo.service. La unidad a activar puede ser controlada por Unit=.
- Tené en cuenta que en caso de que la unidad a activar ya esté activa en el momento en que transcurra el temporizador, no se reiniciará, sino que simplemente se dejará en funcionamiento. En este caso no existe el concepto de generar nuevas instancias de servicio.
- Debido a esto, los servicios con RemainAfterExit= (que se mantiene de forma continua incluso después de que el proceso principal del servicio haya salido) no suelen ser adecuados para la activación a través de temporizadores repetitivos, ya que sólo se activarán una vez, y luego permanecerán para siempre.
- Las unidades de temporización adquieren automáticamente una dependencia Before= del servicio que deben activar.
- Las unidades de temporizadores tendrán automáticamente dependencias de tipo Requires= y After= en sysinit.target, una dependencia de tipo Before= en timers.target, así como Conflicts= y Before= en shutdown.target para asegurar que se detienen limpiamente antes del apagado del sistema.
Para listar todos los temporizadores disponibles en tu entorno utilizá
# systemctl list-timers
Paso 1: Crear un script de ejemplo
Para ejecutar el script después de 5 minutos del arranque con systemd crearemos un script que pondrá algún contenido en un archivo vacío.
# cat /tmp/script_retardo.sh
/bin/bash
echo "Hola, se me hace tarde" >> /tmp/file
Damos permiso de ejecución al script
# chmod u+x /tmp/script_retardo.sh
Paso 2: Creamos el archivo de servicio de la unidad systemd para ejecutar el script después de N minutos del arranque
Aquí debemos crear un archivo de servicio de la unidad systemd y un archivo de temporizado de la unidad systemd correspondiente para ejecutar el script después de N minutos del arranque. Para hacer esto en Linux podemos usar OnBootSec= u OnStartupSec=.
Paso 2.1: OnBootSec vs OnStartupSec
OnBootSec= Define un temporizador relativo al momento en que la máquina fue arrancada. En los contenedores, para la instancia del gestor del sistema, esto se asigna a OnStartupSec=, haciendo que ambos sean equivalentes.
OnStartupSec= Define un temporizador relativo a cuando el gestor de servicios se inició por primera vez. Para las unidades de temporización del sistema esto es muy similar a OnBootSec= ya que el gestor de servicios del sistema se inicia generalmente muy temprano en el arranque. Es principalmente útil cuando se configura en unidades que se ejecutan en el gestor de servicios por usuario, ya que el gestor de servicios por usuario se inicia generalmente sólo en el primer inicio de sesión, no ya durante el arranque.
# cat /etc/systemd/system/ejecutar-script-con-retardo.service
[Unit] Description=Ejecutar script al inicio
[Service] Type=simulacro ExecStart=/tmp/script_retardo.sh TimeoutStartSec=0
NOTA:
Si se coloca la sección [Timer] en el archivo de unidad .service, se producirá el error “systemctl failure with unknown section Timer”. [Timer] debe usarse sólo en el archivo de unidad .timer
Paso 3: Archivo de unidad systemd timer para ejecutar el script después de N minutos de arranque
timer es un archivo de configuración de la unidad cuyo nombre termina en “.timer” codifica información sobre un temporizador controlado y supervisado por systemd.
# cat /etc/systemd/system/ejecutar-script-con-retardo.timer [Unit] Description="Ejecutar el script después de 5 minutos de arranque"
[Timer] OnBootSec=5min [Install] WantedBy=default.target
SUGERENCIA:
La unidad que se activará cuando este temporizador transcurra se proporciona utilizando Unit= en [Timer]. En este caso, como nuestro servicio systemd y el archivo del temporizador tienen el mismo nombre, es decir, ejecutar-script-con-retardo, no hemos definido ninguna Unit= en el archivo de la unidad del temporizador. En caso de que los nombres de tus servicio de unidad y del archivo del temporizador sean diferentes, entonces proporciona el nombre del archivo de servicio mapeado con Unit= en el archivo .timer bajo [Timer].
Aquí para OnBootSec o OnStartupSec,
Los argumentos de las directivas son intervalos de tiempo configurados en segundos. Ejemplo: OnBootSec=50 significa 50s después del arranque.
El argumento también puede incluir unidades de tiempo. Ejemplo: OnBootSec=5h 30min significa 5 horas y 30 minutos después del arranque.
Para más detalles sobre la sintaxis de los intervalos de tiempo soportados con OnBootSec= u OnStartupSec= consulta la página man de systemd.timer
Actualizá los archivos de configuración de systemd
# systemctl daemon-reload
Desactivamos el archivo de servicio de la unidad systemd, ya que este no debe iniciarse automáticamente, que es la idea detrás de este artículo. Queremos que este servicio ejecute el script después de N minutos de arranque basado en el valor del temporizador.
# systemctl disable ejecutar-script-con-retardo.service
Eliminamos /etc/systemd/system/default.target.wants/ejecutar-script-con-retardo.service.
A continuación, habilitamos el archivo de temporizador de la unidad systemd para que se ejecute después del arranque y active el archivo de servicio de la unidad systemd asignada en función del valor del temporizador.
# systemctl enable ejecutar-script-con-retardo.timer
Created symlink /etc/systemd/system/default.target.wants/ejecutar-script-con-retardo.timer → /etc/systemd/system/ejecutar-script-con-retardo.timer.
Luego reiniciamos el nodo.
Paso 4: Verificar la configuración del archivo de unidad systemd
Tras el reinicio, cuando comprobamos el estado de ejecutar-script-con-retardo.timer, observamos la sección resaltada en la que se muestra el siguiente disparo previsto para después de 5 minutos que hemos configurado con OnBootSec en el archivo de unidad de temporización.
# systemctl status ejecutar-script-con-retardo.timer
● ejecutar-script-con-retardo.timer - "Ejecutar script después de 5 minutos de arranque"
Cargado: cargado (/etc/systemd/system/ejecutar-script-con-retardo.timer; habilitado; preconfigurado por el proveedor: deshabilitado)
Activo: activo (esperando) desde Thu 2020-01-16 14:34:34 IST; hace 27s
Activado: Thu 2020-01-16 14:39:30 IST; hace 4min 27s
Una vez que se alcanza el tiempo de activación, el servicio realizará su tarea definida, que en este caso es la de ejecutar el script después de 5 minutos de haber arrancado. Como se puede ver ahora el disparador está mostrando “no aplicable” para la unidad de temporizador
#systemctl status ejecutar-script-con-retardo.timer
● ejecutar-script-con-retardo.timer - "Ejecutar script después de 5 minutos de arranque"
Cargado: cargado (/etc/systemd/system/ejecutar-script-con-retardo.timer; habilitado; preestablecido por el proveedor: deshabilitado)
Activo: activo (transcurrido) desde Thu 2020-01-16 14:34:34 IST; hace 5min
Activación: n/a
Jan 16 14:34:34 equipo.ejemplo.com systemd[1]: Iniciado "Ejecutar script después de 5 minutos de arranque".
También verifica el contenido de nuestro archivo de salida.
[# cat /tmp/file
Hola, se me hace tarde
Así que como era de esperar nuestro script /tmp/script_retardo.sh fue llamado después de 5 minutos de arranque del sistema sin utilizar ningún trabajo cron.