Programar tareas asíncronas en Ubuntu Server 18.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 18.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.

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

Escribimos el comando y pulsamos la tecla Intro.

Programar-tareas-asíncronas-en-Ubuntu-Server-18.04-LTS-001

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

Contenido predeterminado del archivo /etc/anacrontab.

Programar-tareas-asíncronas-en-Ubuntu-Server-18.04-LTS-002

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-asíncronas-en-Ubuntu-Server-18.04-LTS-003

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

Incluso podemos comprobar la última vez que se ejecutó cualquiera de las tareas, consultando el contenido del archivo correspondiente. Por ejemplo, para comprobar cuando se ejecutó por última vez cron.daily, escribiríamos esto:

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

Observa que para ver su contenido hemos necesitado privilegios administrativos. Así se evita que pueda hacerlo cualquier usuario.

Obtenemos el resultado en formato año, mes y día (AAAAMMDD).

Programar-tareas-asíncronas-en-Ubuntu-Server-18.04-LTS-004

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.

Y hasta aquí la teoría, pero creo que quedará más claro si ponemos un ejemplo…

Cómo crear una nueva tarea que se ejecute cada día

Una vez que hemos entendido el método de funcionamiento de anacron, debo hacerte una advertencia: el programa no viene instalado de forma predeterminada, por lo que, antes de nada, comenzaremos instalándolo:

sudo apt install anacron

Como anacron se encuentra en los repositorios, solo tenemos que escribir el comando y pulsamos la tecla Intro.

Programar-tareas-asíncronas-en-Ubuntu-Server-18.04-LTS-005

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-asíncronas-en-Ubuntu-Server-18.04-LTS-006

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

Nuestro ejemplo

Para nuestro ejemplo, 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.

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-asíncronas-en-Ubuntu-Server-18.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-asíncronas-en-Ubuntu-Server-18.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-asíncronas-en-Ubuntu-Server-18.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-asíncronas-en-Ubuntu-Server-18.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-asíncronas-en-Ubuntu-Server-18.04-LTS-011

Por último, ejecutaremos el script para comprobar que funciona (recuerda que necesitamos los privilegios administrativos que hemos usado para crearlo:

sudo /home/usuario/prueba.sh

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

Programar-tareas-asíncronas-en-Ubuntu-Server-18.04-LTS-012

Y para comprobar que ha funcionado usamos el comando ls.

Comprobamos que aparece el script, el archivo original y el archivo copiado.

Programar-tareas-asíncronas-en-Ubuntu-Server-18.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-asíncronas-en-Ubuntu-Server-18.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-asíncronas-en-Ubuntu-Server-18.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-asíncronas-en-Ubuntu-Server-18.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-asíncronas-en-Ubuntu-Server-18.04-LTS-017

También podemos comprobar que se ha creado el archivo con la marca de tiempo en la ruta /var/spool/anacron/:

ls -l /var/spool/anacron/

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

Programar-tareas-asíncronas-en-Ubuntu-Server-18.04-LTS-018

Y para terminar, comprobaremos el contenido del archivo, para ver si el valor de la marca de tiempo es correcta:

sudo cat /var/spool/anacron/somebooks

También en este caso el valor coincide con lo esperado.

Programar-tareas-asíncronas-en-Ubuntu-Server-18.04-LTS-019

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