02 abril 2012

Programando tareas en Lignux con at, batch, cron y anacron

Si queremos programar tareas en Lignux, contamos con diversas herramientas que permiten automatizarlas. Podemos dividirlas en estas categorías: herramientas para ejecutar tareas regularmente, en un momento concreto o cuando el sistema tenga un nivel de carga bajo.

Para ejecutar tareas en un momento concreto, contamos con el comando at; para ejecutarlas cuando nos encontramos con un nivel de carga bajo, podemos utilizar también at o batch, siendo ambos comandos del mismo paquete; y para ejecutarlas de forma regular, utilizaremos cron. Los tres comandos se instalarán, al menos en Debian, si instaláis el paquete lsb-core.

Programando tareas con at

Para programar tareas ejecutaremos el comando at con una fecha del estilo HH:MM [DD.MM.AAAA] [ + desfase], donde el desfase puede ser un número y una unidad (minute, hour, day, week, month, year); los [ ] indican que el parámetro es opcional. También podemos usar horas con formato HH AM/PM.

Tras ejecutar el comando, se nos mostrará un prompt donde podremos introducir los comandos; para finalizar, pulsamos Ctrl+D. También es posible almacenar los comandos a ejecutar, separados por saltos de línea, en un fichero de texto y pasárselo al at con la opción -f archivo.

También es posible añadir los tareas a colas de prioridades con la opción -q letra, donde la letra puede ser una letra de la a a la z, mayúscula o minúscula; nos centraremos en la minúsculas. Con las letras minúsculas podemos establecer la prioridad (nice) que tendrá el proceso cuando se ejecute. Así, los procesos en la cola a (por defecto), se ejecutarán con un valor nice 2, mientras que los de la cola b, c, d... se ejecutarán con un valor nice de 4, 6, 8, etc. respectivamente, obteniendo una prioridad inferior. Cabe decir que la cola b es una cola especial de batch que explicaremos más adelante.

Finalmente, podemos gestionar las tareas con los siguientes comandos:

$ at -l # lista las tareas programadas, cuando se ejecutarán y en qué cola están
$ at -c id # muestra los comandos a ejecutar por la tarea con identificador id
$ at -r id # elimina la tarea con identificador id

Programando tareas con batch

Utilizaremos batch cuando queramos programar tareas para cuando el sistema se encuentre con un bajo nivel de carga. Funciona de la misma forma que at: ejecutamos batch y nos aparecerá un prompt donde podemos escribir los comandos a ejecutar. A diferencia de at, batch no acepta ninguna opción ni flag.

Gestionaremos las tareas programadas con los mismos comandos que hemos visto con at.

También es posible programar tareas en modo batch con at utilizando la cola b o las colas con letra mayúscula; de esta forma, las tareas encoladas en la cola A se ejecutarán a partir del momento que hayamos especificado con un valor nice 2, siguiendo el mismo mecanismo que hemos explicado antes.

Programando tareas con cron

Con cron podemos programar tareas que se tienen que ejecutar de forma periódica.

Dado que por defecto cron viene configurado para que sólo pueda ser ejecutado por el usuario root, debemos editar, o crear si fuese necesario, el archivo /etc/cron.allow y añadir los usuarios, uno por línea, que queremos que puedan programar tareas con cron.

Una vez habilitado el uso de cron, podemos editar las tareas a programar con el comando crontab -e que abrirá un editor en el que os mostrará información y una de sus últimos comentarios será así:

# m h  dom mon dow   command

Esta es una guía de cómo debemos introducir los parámetros que definen cuando se tiene que ejecutar un comando: la m y la h es el minuto y la hora en que se ejecutará el comando; un * indica en cualquier minuto u hora. Dom significa day of month, es decir, que día del mes se ejecutará el comando, del 1 al 31; mon se refiere a month, el mes, del 1 al 12; dow significa day of week, qué día de la semana se ejecutará, del 1 al 7; finalmente, command es el comando que se ejecutará. En cualquiera de los parámetros, exceptuando el parámetro de comando, soporta el asterisco (*), que viene a decir que es indiferente; sin embargo, podemos escribir */10, que si lo ponemos en el campo de minutos, significará que el comando se tiene que ejecutar cada 10 minutos. También podemos hacer una lista de números separados por comas (10, 20, 30, etc.), o un intervalo (1-5 en dow significaría de lunes a viernes).

Una vez acabada la edición, guardamos y salimos de crontab; a partir de este momento el comando se ejecutará siempre que la fecha y la hora coincida con la establecida.

Programando tareas con anacron

No lo he mencionado anteriormente, pues no es instala por defecto con el paquete lsb-core, además de tener una finalidad un tanto peculiar: anacron se utiliza para programar tareas que se tienen que ejecutar a partir de cierto periodo de tiempo, pero durante ese periodo de tiempo nuestro sistema no tiene porqué estar encendido. Por ejemplo, si yo quiero realizar una copia de seguridad como máximo cada 7 días, pero no puedo asegurar que mi PC esté siempre encendido a una hora concreta, no podría programarlo con cron, sino que debería hacerlo con anacron.

De esta manera, cada vez que ejecutemos anacron, comprobará la última ejecución de la tarea, y si es superior a los días indicados, volverá a ejecutarla.

Si queremos instalar anacron, ejecutaremos como root:

# aptitude install anacron

Por defecto, anacron sólo es ejecutado por el usuario root, y no tiene un sistema similar al de cron, que nos permita autorizar la ejecución periódica, entre otras cosas porque anacron no es un demonio que se mantenga comprobando el estado de las tareas, sino que se ejecuta al inicio del sistema o una vez al día mediante cron.

Sin embargo, es posible indicarle a anacron una configuración de usuario y un directorio donde almacenará la información sobre las tareas ejecutadas:

/usr/sbin/anacron -t anacrontab -S directorio

Tenemos que tener en cuenta que si ejecutamos anacron de esta manera, deberemos ejecutarlo de forma manual o bien programando una tarea con cron cada pocas horas o bien como una tarea al inicio de sesión con, por ejemplo, gnome-session-properties; o bien editar como usuario root el archivo /etc/anacrontab.

Veamos ahora cómo se estructura un archivo de configuración de anacron, conocido como anacrontab, en un comentario:

# period  delay  job-identifier  command

Como se puede ver, el primer elemento es el periodo, en días, en el cual queremos que se repita la tarea; el periodo puede ser también la palabra @monthly, que hará que se ejecute una vez al mes, independientemente de los días que tenga ese mes. El delay indica el timepo de espera en minutos que tardará en ejecutarse la tarea; esto se usa para no ejecutar de golpe todos las tareas o para dar tiempo a que el sistema acabe de iniciarse. El job-identifier es una palabra que identifica la tarea de forma única, como podria ser mantenimiento.diario; anacron utiliza este identificador para gestionar la información que guarda en el directorio especificado por la opción -S, o /var/spool/anacron por defecto. Finalmente, el último parámetro es el comando a ejecutar.

Sobre la ejecución de los comandos

En todos los casos mencionados, se ejecutará como intérprete el shell en /bin/sh (se puede reasignar utilizando la variable SHELL) y puede que las variables de entorno no estén asignadas (en el caso de cron debes establecer la variable PATH si quieres asegurarte de que no tendrás problemas); se pueden utilizar scripts y se pueden asignar variables en los comandos introducidos en at y batch, de la misma forma que haríamos si escribiésemos un script, o bien en el mismo archivo de configuración con cron y anacron.

Un saludo,
Morpheus