Programar tareas asíncronas en Ubuntu Server 20.04 LTS

Publicado por P. Ruiz en

Según el diccionario de la Real Academia Española de la Lengua, algo es asíncrono cuando «no tiene lugar en completa correspondencia temporal con otro proceso o con la causa que lo produce«. En nuestro caso, trataremos la programación de tareas asíncronas como un complemento de las tareas programadas estándares. Es decir, aquellas que realizan una determinada tarea cuando llegue un momento preciso del futuro (puedes consultar el artículo Programar una tarea repetitiva en Ubuntu Server 20.04 LTS).

Sin embargo, ¿qué sucede cuando necesitamos ejecutar una tarea, de forma ineludible, pero el ordenador está apagado en el momento de realizarla? Precisamente, de esto es de lo que se encargan las tareas asíncronas y, en particular, el servicio anacron (el nombre proviene del inglés anachronistic cron).

El artículo de hoy lo hemos desarrollado sobre Ubuntu Server pero, para ponerlo en práctica sobre la versión de escritorio, solo tienes que abrir una ventana de terminal. Por ejemplo, usando la combinación de teclas Alt + Control + T.

Antes de comenzar

Antes de comenzar a explicar el funcionamiento de anacron, debo hacerte una advertencia: el programa no viene instalado de forma predeterminada. Sin embargo, se encuentra en los repositorios oficiales de Ubuntu, por lo que instalarlo será tan sencillo como ejecutar el siguiente comando:

sudo apt install anacron

Escribir el comando y pulsamos la tecla Intro.

Programar-tareas-asincronas-en-Ubuntu-Server-20.04-LTS-001

Como no tiene ningún tipo de dependencias, solo tendremos que esperar un instante.

Poco después, el programa estará listo para usarlo.

Programar-tareas-asincronas-en-Ubuntu-Server-20.04-LTS-002

De cualquier modo, antes de continuar, te recomiendo que reinicies el sistema. Así que anacron creará sus archivos de trabajo. Lo puedes lograr ejecutando el siguiente comando:

sudo reboot

Reiniciamos el equipo

Programar-tareas-asincronas-en-Ubuntu-Server-20.04-LTS-003

Cómo funciona anacron

A diferencia de cron, anacron es ejecutado por los scripts de inicio del sistema o por alguna tarea programada y, cuando acaba su trabajo, deja de ejecutarse. Durante su funcionamiento comprueba si ha vencido el plazo de alguna tarea prevista.

Como veremos más adelante, anacron también atiende las tareas asignadas a cron con un periodo diario (daily), semanal (weekly) o mensual (monthly). Sin embargo, no atiende trabajos que cron deba atender cada hora (hourly).

Para llevar a cabo su trabajo, anacron mantiene archivos con marcas de tiempo en la carpeta /var/spool/anacron, que le permiten saber en qué momento se han ejecutado por última vez las tareas (también veremos más detalles después).

En cuanto a las tareas que deben ejecutarse, se encuentran definidas en el archivo /etc/anacrontab. Cada vez que se ejecuta, anacron recorre la lista y, para cada tarea, comprueba si ha pasado el número adecuado de días desde su última ejecución. Si es necesario, la ejecuta.

Para acabar de entenderlo, podemos analizar el aspecto del archivo /etc/anacrontab recurriendo a un editor de textos:

sudo nano /etc/anacrontab

Ejecutamos el comando

Programar-tareas-asincronas-en-Ubuntu-Server-20.04-LTS-004

Un momento después, tendremos el contenido del archivo en la pantalla:

Contenido predeterminado del archivo /etc/anacrontab.

Programar-tareas-asincronas-en-Ubuntu-Server-20.04-LTS-005

Como vemos, al principio del archivo se declaran cuatro variables de entorno para establecer algunos valores predeterminados:

  • SHELL: El intérprete de comandos que se usará para la ejecución de las tareas.

  • PATH: La ruta donde se buscarán los ejecutables que no incluyan la ruta de forma explícita.

  • HOME: La ruta que actuará como directorio predeterminado.

  • LOGNAME: El nombre de la cuenta de usuario bajo la que se ejecutarán las tareas.

Debajo, cada línea definirá una tarea diferente e incluirá los siguientes valores:

  • El periodo de ejecución. Indica la frecuencia con la que debe ejecutarse la tarea. Puede contener parámetros como @daily, @weekly o @monthly (que, como habrás imaginado, equivalen a periodos diarios, semanales o mensuales) o valores numéricos, como 1 (diario), 7 (semanal) o un número diferente, para otros periodos.

  • Un retraso en minutos. Indica el número de minutos que debe esperar el sistema para ejecutar la tarea después de ejecutar anacron. Su objetivo es evitar una avalancha de tareas ejecutándose a la vez cuando arrancamos el sistema.

  • El nombre de la tarea. Puede ser cualquier conjunto de caracteres, excepto la barra (/), pero debe ser único, porque será el nombre que utilice anacron para crear el archivo en /var/spool/anacron, donde guarda la fecha de la última vez que la ha ejecutado.

  • La tarea a realizar.

En cuanto a los archivos con marcas de tiempo que se crean en la carpeta /var/spool/anacron, podemos comprobar su existencia simplemente usando el comando ls:

ls -l /var/spool/anacron/

Comprobamos que aparece un archivo por cada una de las líneas contenidas en /etc/anacrontab.

Programar-tareas-asincronas-en-Ubuntu-Server-20.04-LTS-006

También puedes observar que el nombre de los archivos anteriores coincide con el nombre de cada tarea en el archivo /etc/anacrontab.

Si compruebas el contenido de estos archivos justo después de la instalación, comprobarás que están vacíos.

Sin embargo, veremos después cuál es su contenido habitual.

Un ejemplo práctico

Para comprobar el la práctica el funcionamiento de anacron, crearemos un script que copie un archivo, añadiendo al nombre la fecha y la hora en la que se ha realizado la copia.

La idea consiste en tener una copia diaria del mismo archivo, que nos permita volver a la versión que teníamos en una fecha concreta… Pero de ejecutarlo se encargará anacron.

Supondremos que el archivo original se llama prueba.txt y, para simplificar las cosas, estará en la misma ubicación que el script.

Crear el script

Para crear nuestro script, volveremos a hacer uso del editor nano:

sudo nano prueba.sh

Lo ejecutamos con privilegios administrativos porque será así como se ejecute.

Programar-tareas-asincronas-en-Ubuntu-Server-20.04-LTS-007

En el interior del documento, escribiremos algo como esto:

#!/bin/bash
cp /home/usuario/prueba.txt{,.$(date +%F).$(date +%T)}

Como ves, la primera línea identifica al archivo como un script bash y la segunda se limita a usar el comando cp para realizar la copia. Para obtener la fecha del día que que se ejecute, se utiliza la orden date.

Cuando terminemos de escribirlo, salimos del editor pulsando las teclas Ctrl + X.

Programar-tareas-asincronas-en-Ubuntu-Server-20.04-LTS-008

Al hacerlo, el editor nos preguntará si queremos guardar los cambios que hemos realizado.

Para contestar afirmativamente, pulsamos la tecla Y.

Programar-tareas-asincronas-en-Ubuntu-Server-20.04-LTS-009

A continuación, nos da la oportunidad de cambiar el nombre del archivo, por si tuviésemos una versión anterior que quisiéramos mantener.

Como no es nuestro caso, pulsamos la tecla Intro.

Programar-tareas-asincronas-en-Ubuntu-Server-20.04-LTS-010

Una vez que hemos salido del editor, lo siguiente será asegurarnos de que el script va a poder ejecutarse. Para ello, debemos asignarle los permisos suficientes, algo que conseguiremos con el siguiente comando:

sudo chmod 700 prueba.sh

El valor 7 otorga permisos de lectura, escritura y ejecución, el resto de usuario del sistema no tendrán ningún permiso sobre el archivo (0 para los miembro del grupo del propietario, 0 para el resto).

Escribimos el comando y pulsamos la tecla Intro.

Programar-tareas-asincronas-en-Ubuntu-Server-20.04-LTS-011

Por último, ejecutaremos el script para comprobar que funciona (recuerda que necesitamos los privilegios administrativos que hemos usado para crearlo, y que usuario es el nombre de la cuenta que estoy usando):

sudo /home/usuario/prueba.sh

Como antes, escribimos el comando y pulsamos la tecla Intro.

Programar-tareas-asincronas-en-Ubuntu-Server-20.04-LTS-012

Y para comprobar que ha funcionado usamos el comando ls.

Comprobamos que aparece el script, el archivo original y el archivo que ha resultado de la copia.

Programar-tareas-asincronas-en-Ubuntu-Server-20.04-LTS-013

Añadir la tarea al archivo /etc/anacrontab

Lógicamente, lo siguiente será editar el archivo /etc/anacrontab, para incluir una nueva línea con nuestra tarea. Como antes, recurrimos al editor nano:

sudo nano /etc/anacrontab

De nuevo, escribimos el comando y pulsamos la tecla Intro.

Programar-tareas-asincronas-en-Ubuntu-Server-20.04-LTS-014

Cuando aparezca el contenido de /etc/anacrontab en la ventana del editor, nos desplazamos hasta la última línea y escribimos algo como esto:

@daily  1       somebooks       /bin/bash       /home/usuario/prueba.sh

Aunque ya debes interpretar la línea anterior sin problemas, vamos a hacer un pequeño repaso:

  • El periodo va a ser diario.

  • El retraso para su ejecución después de iniciar el sistema será de 1 minuto.

  • La tarea se llamará somebooks.

  • Y la tarea a ejecutar será el intérprete de comandos (/bin/bash), al que le pasaremos como argumento nuestro script con la ruta completa, porque no se encuentra dentro de las rutas indicadas en la variable PATH.

Cuando acabemos de establecer los valores adecuados, saldremos del editor pulsando las teclas Ctrl + X y asegurándonos de guardar los cambios.

Programar-tareas-asincronas-en-Ubuntu-Server-20.04-LTS-015

Cuando se cierre el editor, reiniciamos el sistema para comprobar que todo funciona correctamente:

 sudo reboot

Una vez más, escribimos el comando y pulsamos la tecla Intro.

Programar-tareas-asincronas-en-Ubuntu-Server-20.04-LTS-016

Comprobar el resultado

Cuando concluya el reinicio, todavía tenemos que tener un poco de paciencia. Recuerda que le hemos dado un retraso de 1 minuto antes de que se ejecute.

Una vez transcurrido ese tiempo, comprobamos que el archivo se ha creado:

ls -l

Efectivamente, aparece un nuevo archivo que acaba de crearse

Programar-tareas-asincronas-en-Ubuntu-Server-20.04-LTS-017

Los archivos con las marcas de tiempo

Desde el principio tenemos pendiente la comprobación de los archivos con las marcas de tiempo dentro del directorio /var/spool/anacron/.

Para comenzar, comprobamos su contenido:

ls -l /var/spool/anacron/

Ejecutamos el comando

Programar-tareas-asincronas-en-Ubuntu-Server-20.04-LTS-018

…Y comprobamos que aparece un nuevo archivo, con el nombre de la tarea, creado a la hora esperada.

También podemos comprobar su contenido, para ver si el valor de la marca de tiempo es correcta:

sudo cat /var/spool/anacron/somebooks

Obtenemos el resultado en formato año, mes y día (AAAAMMDD), y también coincide con el valor esperado.

Programar-tareas-asincronas-en-Ubuntu-Server-20.04-LTS-019

Comparando la marca de tiempo del archivo (la última vez que se ejecutó la tarea), la fecha actual y el periodo contenido en el archivo /etc/anacrontab, anacron puede establecer el momento en que debe volver a ejecutar cada tarea.

Incluso podemos comprobar el momento en el que se ejecutaron el resto de las tareas contenidas en anacrontab, por ejemplo, cron.daily:

sudo cat /var/spool/anacron/cron.daily

Y vemos que su valor también coincide con el del último arranque.

Programar-tareas-asincronas-en-Ubuntu-Server-20.04-LTS-020

Observa lo fácil que puede resultar para un administrador manipular estos archivos, por ejemplo, cuando está haciendo pruebas de funcionamiento de algún script. Solo habría que cambiar el contenido del archivo en función las necesidades… O incluso borrarlo, si es lo que nos interesa.

Y esto es todo por ahora. Como siempre, espero que te resulte útil.