Usar temporizadores systemd en lugar de trabajos cron

Actualmente estoy en el proceso de reemplazar mis trabajos cron con temporizadores systemd. He estado usando temporizadores durante varios años, pero generalmente no profundicé en las complejidades de su uso, descubriendo solo lo que se necesitaba para completar la tarea que me interesaba. Recientemente trabajé en una serie de artículos sobre systemd y descubrí que los temporizadores de systemd tienen algunas características muy interesantes.







Estos temporizadores, como los trabajos cron, pueden, en un momento dado, desencadenar varias acciones en el sistema. Por ejemplo, ejecutar programas o scripts de shell. Los temporizadores pueden funcionar, por ejemplo, una vez al día y solo los lunes. Otro ejemplo es un temporizador que se dispara cada 15 minutos durante el horario comercial (de 8 am a 6 pm). Pero los temporizadores systemd pueden hacer algo que los trabajos cron no pueden. Por ejemplo, un temporizador puede llamar a un script o programa un tiempo específico después de un evento. Tal evento podría ser el inicio del sistema o el inicio de systemd, la finalización de una tarea anterior o incluso la terminación de un servicio que fue llamado previamente por un temporizador.



Temporizadores utilizados para el mantenimiento del sistema



Cuando Fedora u otra distribución de Linux basada en systemd se instala en una computadora, se crean varios temporizadores como parte de las rutinas de mantenimiento del sistema. Estos procedimientos se realizan automáticamente en cualquier sistema Linux. Los temporizadores correspondientes desencadenan varias tareas de servicio, como actualizar las bases de datos del sistema, borrar directorios temporales, rotar archivos de registro, etc.



Como ejemplo, daré aquí información sobre los temporizadores que están disponibles en la máquina virtual que utilicé para los experimentos. Aquí, para obtener una lista de todos los temporizadores, utilicé el comandosystemctl status *timer... El comodín de asterisco juega el mismo papel aquí que en otros comandos similares. Es decir, le dice al sistema que estamos interesados ​​en todas las unidades de temporizador (también llamadas "archivos de unidad de temporizador" o "unidades de temporizador") de systemd:



[root@testvm1 ~]# systemctl status *timer
● mlocate-updatedb.timer - Updates mlocate database every day
     Loaded: loaded (/usr/lib/systemd/system/mlocate-updatedb.timer; enabled; vendor preset: enabled)
     Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
    Trigger: Fri 2020-06-05 00:00:00 EDT; 15h left
   Triggers: ● mlocate-updatedb.service

Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Updates mlocate database every day.

● logrotate.timer - Daily rotation of log files
     Loaded: loaded (/usr/lib/systemd/system/logrotate.timer; enabled; vendor preset: enabled)
     Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
    Trigger: Fri 2020-06-05 00:00:00 EDT; 15h left
   Triggers: ● logrotate.service
       Docs: man:logrotate(8)
             man:logrotate.conf(5)

Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Daily rotation of log files.

● sysstat-summary.timer - Generate summary of yesterday's process accounting
     Loaded: loaded (/usr/lib/systemd/system/sysstat-summary.timer; enabled; vendor preset: enabled)
     Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
    Trigger: Fri 2020-06-05 00:07:00 EDT; 15h left
   Triggers: ● sysstat-summary.service

Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Generate summary of yesterday's process accounting.

● fstrim.timer - Discard unused blocks once a week
     Loaded: loaded (/usr/lib/systemd/system/fstrim.timer; enabled; vendor preset: enabled)
     Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
    Trigger: Mon 2020-06-08 00:00:00 EDT; 3 days left
   Triggers: ● fstrim.service
       Docs: man:fstrim

Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Discard unused blocks once a week.

● sysstat-collect.timer - Run system activity accounting tool every 10 minutes
     Loaded: loaded (/usr/lib/systemd/system/sysstat-collect.timer; enabled; vendor preset: enabled)
     Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
    Trigger: Thu 2020-06-04 08:50:00 EDT; 41s left
   Triggers: ● sysstat-collect.service

Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Run system activity accounting tool every 10 minutes.

● dnf-makecache.timer - dnf makecache --timer
     Loaded: loaded (/usr/lib/systemd/system/dnf-makecache.timer; enabled; vendor preset: enabled)
     Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
    Trigger: Thu 2020-06-04 08:51:00 EDT; 1min 41s left
   Triggers: ● dnf-makecache.service

Jun 02 08:02:33 testvm1.both.org systemd[1]: Started dnf makecache –timer.

● systemd-tmpfiles-clean.timer - Daily Cleanup of Temporary Directories
     Loaded: loaded (/usr/lib/systemd/system/systemd-tmpfiles-clean.timer; static; vendor preset: disabled)
     Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
    Trigger: Fri 2020-06-05 08:19:00 EDT; 23h left
   Triggers: ● systemd-tmpfiles-clean.service
       Docs: man:tmpfiles.d(5)
             man:systemd-tmpfiles(8)

Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Daily Cleanup of Temporary Directories.


Cada temporizador está asociado con al menos seis líneas que contienen información sobre él:



  • La primera línea contiene el nombre del archivo del temporizador y una breve descripción del propósito de la existencia del temporizador.
  • La segunda línea muestra información sobre el estado del temporizador. Es decir, informa si está cargado, proporciona la ruta completa al archivo del temporizador, muestra el estado preestablecido del proveedor (desactivado o activado).
  • La tercera línea muestra información sobre la actividad del temporizador, que incluye información sobre cuándo se activó el temporizador.
  • La cuarta línea contiene la fecha y hora del próximo inicio del temporizador y el tiempo restante aproximado hasta que comience.
  • La quinta línea da el nombre del servicio o evento llamado por el temporizador.
  • Algunos (pero no todos) archivos de unidad de temporizador systemd contienen referencias a la documentación. Estos indicadores están, en mi ejemplo, en las descripciones de tres temporizadores.
  • La última línea de la descripción del temporizador es la entrada de registro asociada con la instancia más reciente del servicio llamado por el temporizador.


Si intenta ejecutar un comando en su computadora systemctl status *timer, el conjunto de temporizadores que se le presenta puede diferir del mío.



Creación de temporizador



Aunque podríamos averiguar los detalles de cómo funcionan los temporizadores analizando cualquier temporizador existente, sugiero crear su propio archivo de unidad de servicio (archivo de configuración de servicio , unidad de servicio ) y un archivo de temporizador con el que se llamará al servicio correspondiente. Estamos aquí, para no complicar la historia, dar un ejemplo bastante trivial. Pero una vez que lo solucionemos, le resultará más fácil comprender el trabajo de otros temporizadores.



Primero, creemos un archivo de configuración de servicio simple que ejecutará algo tan simple como un comando free. Por ejemplo, esto puede ser necesario si necesitamos monitorear regularmente la cantidad de memoria libre. Creemos un archivo de unidad nombrado myMonitor.serviceen la carpeta /etc/systemd/system. No tiene que ser ejecutable.



# This service unit is for testing timer units
# By David Both
# Licensed under GPL V2
#

[Unit]
Description=Logs system statistics to the systemd journal
Wants=myMonitor.timer

[Service]
Type=oneshot
ExecStart=/usr/bin/free

[Install]
WantedBy=multi-user.target


Este archivo es probablemente el archivo de configuración de servicio más simple. Ahora verifiquemos su estado y probémoslo para asegurarnos de que funciona como se esperaba.



[root@testvm1 system]# systemctl status myMonitor.service
● myMonitor.service - Logs system statistics to the systemd journal
     Loaded: loaded (/etc/systemd/system/myMonitor.service; disabled; vendor preset: disabled)
     Active: inactive (dead)
[root@testvm1 system]# systemctl start myMonitor.service
[root@testvm1 system]#


¿Por qué no se envía nada a la consola? Esto se debe a que, de forma predeterminada, la salida estándar ( stdout) de los programas iniciados por systemd utilizando archivos de unidad de servicio se redirige al registro de systemd. Debido a esto, al menos mientras existan los registros correspondientes, estos registros pueden ser analizados. Echemos un vistazo al registro y busquemos entradas relacionadas con nuestro servicio y el día que probamos. El comando correspondiente se verá así : journalctl -S today -u myMonitor.service. La clave -Ses una versión abreviada --since. Le permite especificar el período de tiempo durante el cual la utilidadjournalctlbuscando registros. El punto no es que no estemos interesados ​​en resultados anteriores. En nuestro caso, tales resultados simplemente no lo serán. Esta tecla se utiliza para reducir el tiempo que la empresa necesita para buscar datos. Si la computadora ha estado funcionando durante mucho tiempo, se pueden acumular muchas entradas en el registro.



[root@testvm1 system]# journalctl -S today -u myMonitor.service
-- Logs begin at Mon 2020-06-08 07:47:20 EDT, end at Thu 2020-06-11 09:40:47 EDT. --
Jun 11 09:12:09 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...
Jun 11 09:12:09 testvm1.both.org free[377966]:               total        used        free      shared  buff/cache   available
Jun 11 09:12:09 testvm1.both.org free[377966]: Mem:       12635740      522868    11032860        8016     1080012    11821508
Jun 11 09:12:09 testvm1.both.org free[377966]: Swap:       8388604           0     8388604
Jun 11 09:12:09 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.
[root@testvm1 system]#


Una tarea que se inicia mediante un archivo de configuración de servicio se puede representar como un solo programa, una secuencia de programas o un script escrito en cualquier lenguaje de script. Agreguemos myMonitor.serviceotra tarea al archivo de la unidad , incluida la [Service]siguiente al final de la sección :



ExecStart=/usr/bin/lsblk


Iniciemos el servicio nuevamente y revisemos el registro. Debe haber algo allí que se parezca a lo que se muestra a continuación. Es decir, el registro debe contener la salida de datos de ambos comandos:



Jun 11 15:42:18 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...
Jun 11 15:42:18 testvm1.both.org free[379961]:               total        used        free      shared  buff/cache   available
Jun 11 15:42:18 testvm1.both.org free[379961]: Mem:       12635740      531788    11019540        8024     1084412    11812272
Jun 11 15:42:18 testvm1.both.org free[379961]: Swap:       8388604           0     8388604
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: NAME          MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: sda             8:0    0  120G  0 disk
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: ├─sda1          8:1    0    4G  0 part /boot
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: └─sda2          8:2    0  116G  0 part
Jun 11 15:42:18 testvm1.both.org lsblk[379962]:   ├─VG01-root 253:0    0    5G  0 lvm  /
Jun 11 15:42:18 testvm1.both.org lsblk[379962]:   ├─VG01-swap 253:1    0    8G  0 lvm  [SWAP]
Jun 11 15:42:18 testvm1.both.org lsblk[379962]:   ├─VG01-usr  253:2    0   30G  0 lvm  /usr
Jun 11 15:42:18 testvm1.both.org lsblk[379962]:   ├─VG01-tmp  253:3    0   10G  0 lvm  /tmp
Jun 11 15:42:18 testvm1.both.org lsblk[379962]:   ├─VG01-var  253:4    0   20G  0 lvm  /var
Jun 11 15:42:18 testvm1.both.org lsblk[379962]:   └─VG01-home 253:5    0   10G  0 lvm  /home
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: sr0            11:0    1 1024M  0 rom
Jun 11 15:42:18 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.
Jun 11 15:42:18 testvm1.both.org systemd[1]: Finished Logs system statistics to the systemd journal.


Ahora, después de estar seguros de que todo está funcionando correctamente, crearemos, en la carpeta /etc/systemd/system, un archivo de unidad de temporizador, dándole un nombre myMonitor.timer. Agregue lo siguiente al archivo:



# This timer unit is for testing
# By David Both
# Licensed under GPL V2
#

[Unit]
Description=Logs some system statistics to the systemd journal
Requires=myMonitor.service

[Timer]
Unit=myMonitor.service
OnCalendar=*-*-* *:*:00

[Install]
WantedBy=timers.target


La marca OnCalendarde tiempo en este archivo ,, *-*-* *:*:00debería hacer que el temporizador llame a la unidad myMonitor.servicecada minuto. OnCalendarHablaremos más sobre esto a continuación.



Mientras tanto, podemos echar un vistazo a las entradas de registro relacionadas con el inicio del servicio de temporizador. También podemos activar el modo de reloj con temporizador. Sin embargo, monitorear el servicio le permitirá ver los resultados casi en tiempo real. Para hacer esto, necesita ejecutar journalctlcon la tecla -f( follow):



[root@testvm1 system]# journalctl -S today -f -u myMonitor.service
-- Logs begin at Mon 2020-06-08 07:47:20 EDT. --


Inicie el temporizador, pero no lo incluya en el inicio automático al iniciar el sistema. 



[root@testvm1 ~]# systemctl start myMonitor.timer
[root@testvm1 ~]#


Observe lo que sucede por un tiempo.



Uno de los resultados aparece de inmediato. Y los siguientes se mostrarán a intervalos de aproximadamente un minuto. Mire la revista durante unos minutos.



[root@testvm1 system]# journalctl -S today -f -u myMonitor.service
-- Logs begin at Mon 2020-06-08 07:47:20 EDT. --
Jun 13 08:39:18 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...
Jun 13 08:39:18 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.
Jun 13 08:39:19 testvm1.both.org free[630566]:               total        used        free      shared  buff/cache   available
Jun 13 08:39:19 testvm1.both.org free[630566]: Mem:       12635740      556604    10965516        8036     1113620    11785628
Jun 13 08:39:19 testvm1.both.org free[630566]: Swap:       8388604           0     8388604
Jun 13 08:39:18 testvm1.both.org systemd[1]: Finished Logs system statistics to the systemd journal.
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: NAME          MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: sda             8:0    0  120G  0 disk
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: ├─sda1          8:1    0    4G  0 part /boot
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: └─sda2          8:2    0  116G  0 part
Jun 13 08:39:19 testvm1.both.org lsblk[630567]:   ├─VG01-root 253:0    0    5G  0 lvm  /
Jun 13 08:39:19 testvm1.both.org lsblk[630567]:   ├─VG01-swap 253:1    0    8G  0 lvm  [SWAP]
Jun 13 08:39:19 testvm1.both.org lsblk[630567]:   ├─VG01-usr  253:2    0   30G  0 lvm  /usr
Jun 13 08:39:19 testvm1.both.org lsblk[630567]:   ├─VG01-tmp  253:3    0   10G  0 lvm  /tmp
Jun 13 08:39:19 testvm1.both.org lsblk[630567]:   ├─VG01-var  253:4    0   20G  0 lvm  /var
Jun 13 08:39:19 testvm1.both.org lsblk[630567]:   └─VG01-home 253:5    0   10G  0 lvm  /home
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: sr0            11:0    1 1024M  0 rom
Jun 13 08:40:46 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...
Jun 13 08:40:46 testvm1.both.org free[630572]:               total        used        free      shared  buff/cache   available
Jun 13 08:40:46 testvm1.both.org free[630572]: Mem:       12635740      555228    10966836        8036     1113676    11786996
Jun 13 08:40:46 testvm1.both.org free[630572]: Swap:       8388604           0     8388604
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: NAME          MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: sda             8:0    0  120G  0 disk
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: ├─sda1          8:1    0    4G  0 part /boot
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: └─sda2          8:2    0  116G  0 part
Jun 13 08:40:46 testvm1.both.org lsblk[630574]:   ├─VG01-root 253:0    0    5G  0 lvm  /
Jun 13 08:40:46 testvm1.both.org lsblk[630574]:   ├─VG01-swap 253:1    0    8G  0 lvm  [SWAP]
Jun 13 08:40:46 testvm1.both.org lsblk[630574]:   ├─VG01-usr  253:2    0   30G  0 lvm  /usr
Jun 13 08:40:46 testvm1.both.org lsblk[630574]:   ├─VG01-tmp  253:3    0   10G  0 lvm  /tmp
Jun 13 08:40:46 testvm1.both.org lsblk[630574]:   ├─VG01-var  253:4    0   20G  0 lvm  /var
Jun 13 08:40:46 testvm1.both.org lsblk[630574]:   └─VG01-home 253:5    0   10G  0 lvm  /home
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: sr0            11:0    1 1024M  0 rom
Jun 13 08:40:46 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.
Jun 13 08:40:46 testvm1.both.org systemd[1]: Finished Logs system statistics to the systemd journal.
Jun 13 08:41:46 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...
Jun 13 08:41:46 testvm1.both.org free[630580]:               total        used        free      shared  buff/cache   available
Jun 13 08:41:46 testvm1.both.org free[630580]: Mem:       12635740      553488    10968564        8036     1113688    11788744
Jun 13 08:41:46 testvm1.both.org free[630580]: Swap:       8388604           0     8388604
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: NAME          MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: sda             8:0    0  120G  0 disk
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: ├─sda1          8:1    0    4G  0 part /boot
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: └─sda2          8:2    0  116G  0 part
Jun 13 08:41:47 testvm1.both.org lsblk[630581]:   ├─VG01-root 253:0    0    5G  0 lvm  /
Jun 13 08:41:47 testvm1.both.org lsblk[630581]:   ├─VG01-swap 253:1    0    8G  0 lvm  [SWAP]
Jun 13 08:41:47 testvm1.both.org lsblk[630581]:   ├─VG01-usr  253:2    0   30G  0 lvm  /usr
Jun 13 08:41:47 testvm1.both.org lsblk[630581]:   ├─VG01-tmp  253:3    0   10G  0 lvm  /tmp
Jun 13 08:41:47 testvm1.both.org lsblk[630581]:   ├─VG01-var  253:4    0   20G  0 lvm  /var
Jun 13 08:41:47 testvm1.both.org lsblk[630581]:   └─VG01-home 253:5    0   10G  0 lvm  /home
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: sr0            11:0    1 1024M  0 rom
Jun 13 08:41:47 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.
Jun 13 08:41:47 testvm1.both.org systemd[1]: Finished Logs system statistics to the systemd journal.


Asegúrese de verificar tanto el estado del temporizador como el estado del servicio.



¿Lograste notar aquí lo que noté? Es posible que haya notado al menos dos cosas al leer la revista.



En primer lugar, el hecho de que no necesita hacer algo especial para iniciar la sesión ExecStartde myMonitor.serviceescritura stdout. Esta característica es parte de las funciones de inicio estándar de systemd. Pero esto significa que probablemente deba tener cuidado al ejecutar scripts desde archivos de configuración de servicio, teniendo en cuenta la cantidad de datos en los que escriben stdout.



En segundo lugar, es posible que haya notado que el temporizador no comienza exactamente a las:00segundos de cada minuto, y ni siquiera exactamente un minuto después de la última ejecución. Esta es una de las características de dichos temporizadores, si es necesario (o si hiere los sentimientos del administrador del sistema), este comportamiento de los temporizadores se puede cambiar haciéndolos más precisos.



La razón por la que el temporizador no se inicia en :00segundos de cada minuto es porque el sistema tiende a evitar que varios servicios se inicien simultáneamente. Por ejemplo, al configurar el indicador de tiempo, OnCalendarpuede utilizar valores como Weekly, Dailyy otros. Estas formas abreviadas de nombrar puntos en el tiempo están configuradas para que los temporizadores en los que se utilizan comiencen en00:00:00el día correspondiente. Cuando se configuran varios temporizadores de esta manera, es muy probable que se activen todos al mismo tiempo.



Esta es la razón por la que los temporizadores systemd están diseñados deliberadamente para que no se inicien exactamente en el momento especificado, sino con alguna desviación aleatoria de este. Esta desviación no se puede llamar completamente accidental. Los temporizadores comienzan en algún lugar de una ventana de tiempo que comienza en el momento especificado y termina a un minuto del original. Este tiempo, de acuerdo con la documentación para systemd.timer, se mantiene en un estado estable, teniendo en cuenta todos los demás temporizadores declarados en el sistema. En el fragmento de registro anterior, puede ver que el temporizador se activa inmediatamente después de que se inicia, y luego aproximadamente 46 o 47 segundos después del inicio de cada minuto siguiente.



Muy a menudo, este enfoque probabilístico para determinar el momento exacto de los temporizadores se adapta a todos. Cuando se programan tareas como hacer una copia de respaldo de algo, siempre que dichas tareas se realicen fuera del horario comercial, esto no causa ningún problema. El administrador del sistema, al configurar trabajos cron, puede especificar horas claramente definidas para iniciarlos, algo así como 01:05:00intentar asegurarse de que estos trabajos no entren en conflicto con otros. Existe una amplia gama de formas de especificar el tiempo que lo permiten. Los cambios aleatorios en la hora de inicio de una tarea que no superan el minuto no suelen tener un papel especial.



Pero para algunas tareas, la sincronización exacta del temporizador es extremadamente importante. En tales casos, al configurar los temporizadores, puede especificar un tiempo más preciso de su funcionamiento (hasta la precisión medida en microsegundos). Esto se hace agregando al archivo de descripción del temporizador, en la sección Timer, una construcción que se parece a la siguiente:



AccuracySec=1us


Puede utilizar palabras clave especiales para especificar la precisión deseada del temporizador. Estas palabras clave también se pueden utilizar al configurar eventos recurrentes y únicos. El sistema comprende las siguientes palabras clave:



  • Microsegundo: usec, us, µs.
  • Milisegundo: msec, ms.
  • Segundo: seconds, second, sec, s.
  • Minuto: minutes, minute, min, m.
  • Hora: hours, hour, hr, h.
  • Día: days, day, d.
  • Semana: weeks, week, w.
  • Mes: months, month, M(el mes se define como 30,44 días).
  • Año: years, year, y(el año se define como 365,25 días).


Todos los temporizadores estándar disponibles se /usr/lib/systemd/systemconfiguran utilizando rangos mucho más largos que establecen la precisión de su activación, ya que en el caso de estos temporizadores, su activación en un tiempo estrictamente especificado no es particularmente importante. Eche un vistazo a las especificaciones de algunos de los temporizadores generados por el sistema:



[root@testvm1 system]# grep Accur /usr/lib/systemd/system/*timer
/usr/lib/systemd/system/fstrim.timer:AccuracySec=1h
/usr/lib/systemd/system/logrotate.timer:AccuracySec=1h
/usr/lib/systemd/system/logwatch.timer:AccuracySec=12h
/usr/lib/systemd/system/mlocate-updatedb.timer:AccuracySec=24h
/usr/lib/systemd/system/raid-check.timer:AccuracySec=24h
/usr/lib/systemd/system/unbound-anchor.timer:AccuracySec=24h
[root@testvm1 system]#


Para comprender mejor la estructura interna de los archivos del temporizador del directorio /usr/lib/systemd/system, puede ver su contenido.



No es necesario configurar nuestro temporizador de aprendizaje para que se active cuando se inicie el sistema. Sin embargo, si lo desea, puede usar el siguiente comando para esto:



[root@testvm1 system]# systemctl enable myMonitor.timer


Los archivos de temporizador que creará no necesitan ser ejecutables. Además, no es necesario configurar los archivos de configuración del servicio para que se activen en el arranque, ya que los temporizadores los llaman. Si es necesario, el servicio también se puede llamar manualmente desde la línea de comando. Pruebe esto y busque en el registro de systemd.



Para obtener más información sobre la precisión de los temporizadores, cómo especificar el tiempo de activación de eventos y cómo activar eventos, consulte la documentación de systemd.timery systemd.time.



Tipos de temporizador



Los temporizadores de Systemd tienen otras características que los trabajos cron no tienen, "únicos" o repetitivos, que se llaman solo con fechas en tiempo real y en tiempo real. Los temporizadores de Systemd se pueden configurar para que se llamen en función de los cambios en el estado de otras unidades de Systemd. Por ejemplo, el temporizador se puede configurar para que se active después de un tiempo específico después de que se inicie el sistema, después de que el usuario inicie sesión en él o después de un tiempo específico después de activar un determinado servicio. Estos temporizadores se denominan monótonos. Estos temporizadores se restablecen después de cada reinicio del sistema.



La siguiente tabla muestra una lista de temporizadores monotónicos con una breve descripción de cada uno de ellos. También hay una descripción del temporizador.OnCalendar, que no es monótono y se utiliza en casos en los que necesita organizar un lanzamiento único o repetido de algo en el futuro. Esta tabla se basa en documentación systemd.timer.

Temporizador Monótono Descripción
OnActiveSec=


X El tiempo de funcionamiento del temporizador se establece en relación con el momento de la activación del temporizador.
OnBootSec=


X El temporizador se establece en relación con el momento en que se inicia el sistema.
OnStartupSec=


X . OnBootSec=, . , , , , , .
OnUnitActiveSec=


X , , , .
OnUnitInactiveSec=


X , , , .
OnCalendar=


  . systemd.time(7). OnActiveSec=. — systemd, , cron.


Al configurar temporizadores monótonos, se pueden usar las mismas palabras clave que se describen arriba cuando se habla AccuracySec. Pero debe tenerse en cuenta que systemd convierte los intervalos de tiempo correspondientes en segundos. Por ejemplo, es posible que desee configurar un temporizador que se active una vez, cinco días después de que se inicie el sistema. Puede parecer una descripción de esta manera: OnBootSec=5d. Si la computadora se inició 2020-06-15a las 09:45:27, entonces el temporizador comenzará 2020-06-20a las 09:45:27(o dentro de 1 minuto después de este momento).



Descripción de los eventos del calendario



La aplicación de eventos del calendario es una parte clave de la descripción de los temporizadores que se llaman a intervalos regulares. Analicemos algunas de las características de dichos eventos que se utilizan al configurar el indicador de tiempo OnCalendar.



Systemd y sus temporizadores correspondientes utilizan un formato de fecha y hora diferente al crontab. Este formato es más flexible que el utilizado en crontab. Le permite especificar la fecha y la hora de una manera simplificada, en estilo de comando at. Para aquellos que estén familiarizados con él at, debería ser fácil entender la configuración del temporizador de systemd.



Cuando se utiliza OnCalendar=para configurar temporizadores, se utiliza el siguiente formato básico para especificar la fecha y la hora:



DOW YYYY-MM-DD HH:MM:SS


DOW(Día de la semana) es una parte opcional de la construcción anterior. En otros campos, puede utilizar el símbolo de asterisco ( *) para representar cualquier valor que pueda aparecer en la posición que ocupa. Todas las formas de indicación de fecha y hora se convierten a forma normalizada. Si no se especifica ningún tiempo, se supone que sí 00:00:00. Si no se especifica la fecha, pero se especifica la hora, entonces el temporizador funcionará el día en que comienza (en términos relativos, "hoy") o el día siguiente ("mañana"). Depende de la hora actual. Los meses y días de la semana se pueden nombrar usando sus nombres. Puede utilizar listas de valores separados por comas aquí. Los rangos de valores pueden estar separados por tres puntos ( ) entre el valor inicial y final del rango.



Al especificar fechas, tenemos un par de posibilidades interesantes. Por lo tanto, se puede usar una tilde (~) para indicar el último día de un mes, o para indicar una fecha un número determinado de días antes del último día del mes. La barra inclinada (/) se puede utilizar como modificador para indicar el día de la semana.



La siguiente tabla muestra algunos ejemplos típicos de tiempos usados ​​en una expresión OnCalendar.



Ejemplo de presentación de un evento de calendario DOW YYYY-MM-DD HH:MM:SS

Descripción
*-*-* 00:15:30


Todos los días de todos los meses de cada año, 15 minutos y 30 segundos después de la medianoche.
Weekly


Todos los lunes a las 00:00:00.
Mon *-*-* 00:00:00


Lo mismo que Weekly.
Mon


Lo mismo que Weekly.
Wed 2020-*-*


Todos los miércoles de 2020 a las 00:00:00.
Mon..Fri 2021-*-*


Todos los días de la semana en 2021 a las 00:00:00.
2022-6,7,8-1,15 01:15:00


1 y 15 de junio, julio y agosto de 2022 01:15:00después de la medianoche.
Mon *-05~03


, , , 3 .
Mon..Fri *-08~04


, 4 , .
*-05~03/2


3 , , — , . . , ~.
*-05-03/2


, — . . , (-).


,



Systemd tiene una gran herramienta para verificar y examinar las especificaciones de eventos del calendario. Estamos hablando de un equipo systemd-analyze calendarque analiza las descripciones de los eventos del calendario y las presenta de forma normalizada. Este comando también proporciona otra información interesante, como la fecha y hora del próximo evento de este tipo, y el tiempo aproximado que queda hasta ese momento.



Primero, echemos un vistazo a la especificación, que contiene solo la fecha, no contiene información sobre la hora (tenga en cuenta que las horas en los campos Next elapsey (in UTC)son diferentes, esta diferencia depende de la zona horaria local):



[student@studentvm1 ~]$ systemd-analyze calendar 2030-06-17
  Original form: 2030-06-17                
Normalized form: 2030-06-17 00:00:00        
    Next elapse: Mon 2030-06-17 00:00:00 EDT
       (in UTC): Mon 2030-06-17 04:00:00 UTC
       From now: 10 years 0 months left    
[root@testvm1 system]#


Ahora agreguemos información de tiempo a la descripción. En este ejemplo, la fecha y la hora se analizan por separado, como entidades que no están relacionadas entre sí:



[root@testvm1 system]# systemd-analyze calendar 2030-06-17 15:21:16
  Original form: 2030-06-17                
Normalized form: 2030-06-17 00:00:00        
    Next elapse: Mon 2030-06-17 00:00:00 EDT
       (in UTC): Mon 2030-06-17 04:00:00 UTC
       From now: 10 years 0 months left    

  Original form: 15:21:16                  
Normalized form: *-*-* 15:21:16            
    Next elapse: Mon 2020-06-15 15:21:16 EDT
       (in UTC): Mon 2020-06-15 19:21:16 UTC
       From now: 3h 55min left              
[root@testvm1 system]#


Ahora considere un ejemplo en el que la fecha y la hora se consideran juntas. Para hacer esto, deben ir entre comillas. Pero si usa una construcción de este tipo OnCalendar, no olvide eliminar las comillas, de lo contrario, enfrentará errores:



[root@testvm1 system]# systemd-analyze calendar "2030-06-17 15:21:16"
Normalized form: 2030-06-17 15:21:16        
    Next elapse: Mon 2030-06-17 15:21:16 EDT
       (in UTC): Mon 2030-06-17 19:21:16 UTC
       From now: 10 years 0 months left    
[root@testvm1 system]#


Ahora veamos algo de la tabla anterior. Me gusta especialmente esta descripción de ella:



2022-6,7,8-1,15 01:15:00


Analicémoslo:



[root@testvm1 system]# systemd-analyze calendar "2022-6,7,8-1,15 01:15:00"
  Original form: 2022-6,7,8-1,15 01:15:00
Normalized form: 2022-06,07,08-01,15 01:15:00
    Next elapse: Wed 2022-06-01 01:15:00 EDT
       (in UTC): Wed 2022-06-01 05:15:00 UTC
       From now: 1 years 11 months left
[root@testvm1 system]#


Ahora echemos un vistazo a la descripción Mon *-05~3, pero esta vez le pediremos al programa información sobre los próximos 5 tiempos del temporizador, que usa la siguiente configuración:



[root@testvm1 ~]# systemd-analyze calendar --iterations=5 "Mon *-05~3"
  Original form: Mon *-05~3                
Normalized form: Mon *-05~03 00:00:00      
    Next elapse: Mon 2023-05-29 00:00:00 EDT
       (in UTC): Mon 2023-05-29 04:00:00 UTC
       From now: 2 years 11 months left    
       Iter. #2: Mon 2028-05-29 00:00:00 EDT
       (in UTC): Mon 2028-05-29 04:00:00 UTC
       From now: 7 years 11 months left    
       Iter. #3: Mon 2034-05-29 00:00:00 EDT
       (in UTC): Mon 2034-05-29 04:00:00 UTC
       From now: 13 years 11 months left    
       Iter. #4: Mon 2045-05-29 00:00:00 EDT
       (in UTC): Mon 2045-05-29 04:00:00 UTC
       From now: 24 years 11 months left    
       Iter. #5: Mon 2051-05-29 00:00:00 EDT
       (in UTC): Mon 2051-05-29 04:00:00 UTC
       From now: 30 years 11 months left    
[root@testvm1 ~]#


Creo que hemos cubierto suficientes casos de uso systemd-analyze calendarpara que pueda comenzar a probar sus propias definiciones de eventos de calendario. Tenga en cuenta que la herramienta systemd-analyzetiene otras características interesantes.



Materiales adicionales



Hay muchas publicaciones sobre systemd en Internet, pero en su mayoría son demasiado breves, muy simplistas o incluso con errores. Este artículo proporciona algunas buenas fuentes de información sobre systemd. A continuación se muestra una lista de enlaces a más materiales de calidad sobre este tema. 



  • Una guía práctica para systemd por el Proyecto Fedora.
  • Una hoja de trucos del Proyecto Fedora que mapea los comandos heredados SystemV y systemd.
  • Detalles sobre systemd y por qué se creó.
  • Material con información y asesoramiento, dedicado a systemd.
  • (Lennart Poettering), systemd. , 2010 2011, . systemd .
  • systemd.
  • systemd.




Los temporizadores Systemd se pueden usar para realizar las mismas tareas que hacen los trabajos cron. Pero systemd le brinda más flexibilidad en términos de configuración de calendario y temporizadores monótonos.



Aunque los archivos de configuración del servicio que creamos durante nuestros experimentos generalmente se invocan usando temporizadores, puede llamarlos en cualquier momento usando un comando como systemctl start myMonitor.service. Un temporizador puede iniciar varias tareas. Estos pueden ser, por ejemplo, scripts Bash y utilidades de Linux. Se puede componer un archivo de configuración de servicio para que, cuando se llame, se ejecuten varios scripts. También puede hacer que los scripts se ejecuten por separado.



Si hablamos de la coexistencia de systemd, cron y at, entonces quiero señalar que todavía no he visto ninguna señal de que cron o at estén en desuso. Espero que sigan siendo compatibles, ya que al menos es mucho más fácil de usar que systemd para programar tareas puntuales.



¿Que estas usando? ¿Temporizadores systemd o trabajos cron?






All Articles