4.2.1. Planificación clásica

Es muy, muy común que incluso las distribuciones que han migrado sigan utilizando el procedimiento clásico para ejecutar tareas en el futuro o de forma periódica.

4.2.1.1. Tareas diferidas

Para la ejecución de tareas futuras se usa el comando at:

at [<opciones>] <momento>

La orden recibe las tareas por la entrada estándar y las ejecutará en el momento que se precise como argumento. Las tareas se interpretan con el intérprete al que se refiera /bin/sh. Esto es importante, porque en debian este intérprete no es bash, sino dash. Un ejemplo de uso es el siguiente:

$ echo "touch /tmp/prueba" | at now

Las tareas así indicadas se almacenan en colas. Si no se especifica ninguna, lo harán en la cola «a», aunque puede especificarse otra incluyendo la opción -q. En el ejemplo, el momento que se ha expresado es now, es decir, ahora mismo. Hay bastantes posibilidades distintas:

now

Ahora mismo.

noon

El próximo mediodía.

midnight

La próxima media noche.

teatime

las próximas cuatro de la tarde.

tomorrow

Mañana a esta misma hora.

next week

La próxima semana a esta misma hora.

next month

El próximo mes a esta misma hora.

next monday

El próximo lunes a esta misma hora. Se puede indicar cualquier día de la semana. No es necesario escribir el nombre completo del día, sino que basta con las tres primeras letras (mon, tue, etc.). Es posible ahorrarse la palabra next.

Oct 21, 10/21

El próximo 21 de octubre a esta misma hora.

Oct 21 2017, 10/21/2017

El 21 de octubre de 2017 a esta misma hora.

9am, 9:30am (formato de 12 horas)

Las próximas nueve (y media) de la mañana.

15:00 (formato de 24 horas)

Las próximas tres de la tarde. Tanto en este formato como en el anterior se puede yuxtaponer la hora concreta a alguno de los momentos anteriores: 15:00 next week: dentro de una semana a las tres de la tarde; 9am 10/21/2017: El 21 de octubre de 2017 a las nueve de la mañana.

A todos los momentos citados se le pueden añadir añadir unidades de tiempo (min[utes], hour[s], day[s], week[s], month[s], year[s]):

$ echo "touch /tmp/prueba" | at now + 1 min
[... Dentro de un minuto ...]
$ echo "touch /tmp/prueba" | at monday + 5 hours
[... El próximo lunes cinco horas después de la actual ...]
$ echo "touch /tmp/prueba" | at next week + 1 week
[... Dentro de dos semanas ...]

Son útiles la opción -m, que envía al usuario un mensaje de correo cuando se ha completado la acción; y la opción -f que permite indicar el fichero donde se almacenan las órdenes que se desea ejecutar en diferido.

Cada vez que se se difiere la ejecución de una orden con atq se le asigna a esta un identificador1, de manera que si más adelante se desea conocer en qué consiste esta orden se puede hacer:

$ at -c 10

Suponiendo que la orden que queramos revisar sea la 10. Este número se indica justamente al crear la orden. Ahora bien, ¿cómo hacemos si queremos hacer esta revisión tiempo después y no recordamos en número de la tarea?

atq

Lista las tareas pendientes por ejecutar:

$ atq
6       Sat Oct 21 20:30:00 2017 a usuario
1       Sat Oct 21 17:30:00 2017 a usuario
3       Sat Oct 21 19:30:00 2017 a usuario

El número más a la izquierda es el identificador del trabajo.

atrm

Para cancelar un tarea definida (o varias) antes de que se ejecute:

$ atrm 6 1

Eliminamos las tareas 1 y 6.

4.2.1.2. Planificación periódica de tareas

A diferencia del caso anterior, la planificación implica la ejecución periódica de tareas. Por ejemplo, puede interesarnos realizar una copia semanal de determinada parte del árbol de directorios. Lo conveniente, en este caso, sería que esta copia se llevara a cabo sin nuestra intervención a unas horas en las que preveamos que el servidor no tendrá demasiada carga (p.e. de madrugada),

Para este efecto, existe el demonio cron, que requiere configurarse a través de ficheros de configuración. Cada usuario dispone del suyo particular2 (incluido el propio root) y, además, existe otro fichero general /etc/crontab3.

4.2.1.2.1. Sintaxis de los ficheros

Saber cómo se planifican las tareas es tan fácil como saber la sintaxis de estos ficheros de configuración y esto será lo que tratemos a continuación4.

Tales ficheros están constituidos por líneas con seis o siete columnas, las cinco primeras definen la frecuencia y la última el comando (o los comandos) que se quieren ejecutar. La sexta columna indica el usuario con el que se ejecutarán los comandos, pero no existe en las planificaciones de los usuarios (las que se definen con la orden crontab -e, como se verá más adelante).

Para separar las columnas pueden usarse uno o varios signos de espaciado (espacios o tabuladores). A pesar de ello, en la última columna, la del comando, sí puede haber espacios (o tabulaciones). Como es habitual, una línea que empiece por almohadilla, se considera un comentario. Una línea tipo podría ser la siguiente:

5  4  *  *  7  /usr/local/bin/script.sh parametro1 paramentro2

o bien:

5  4  *  *  7  root /usr/local/bin/script.sh parametro1 paramentro2

si es necesaria la columna que identifica al usuario.

Analicemos las 5 columnas que indican cuándo se debe ejecutar la orden:

minuto

Minuto en que se ejecutará el comando. Por ejemplo, si ponemos 30 estamos indicando que tal comando se ejecutará a las y media (de qué hora lo determina otra columna). Se pueden expresar varios valores separándolos por comas. Por ejemplo, 15,30 significa que queremos ejecutar el comando a las y cuarto y a las y media. Es posible indicar un rango separando los extremos por un guión: 0-30, significa cada minutos entre 0 y 30. También es posible indicar cada ciertos minutos con la sintaxis /X. Por ejemplo, /15 significa cada cuarto de hora, esto es, a las en punto, a las y cuarto, a las y media y a las menos cuarto. Por último, se puede indicar *, que significa que no se fija ningún valor concreto y que, por tanto, se ejecutará la orden cada minuto. En resumen:

  • 30: Valor simple: a las y media.

  • 15,30: Varios valores: a las y cuarto y a las y media.

  • *: En cada valor posible, esto es, cada minuto.

  • 15-35: Rango: entre los quince y los treinta y cinco minutos.

  • /15: Cada quince minutos, el rango que se especifique. Por

    ejemplo, */15 cada quince minutos, todo el rango de minutos posible (0-59).

También pueden mezclarse todas estas notaciones. Por ejemplo 0-10/2 equivale a 0,2,4,6,8,10. O bien, 0-10/2,20,30-40/4,50.

Todas estas notaciones son aplicables a los campos numéricos que aún falta por describir.

hora

Hora del día (0-23) en que se ejecutará el comando.

día del mes

Número entre 1 y 31.

mes

Número entre 1 (enero) y 12 (diciembre).

día de la semana

Numero entre 0 y 7. Tanto el 0 como el 7 representan el domingo.

Consecuentemente, la línea de ejemplo que se indicó más arriba provoca que la orden se ejecute todos los domingos a la 4:05 de la madrugada.

4.2.1.2.2. Estructura de los ficheros

Ya se ha dejado dicho que cada usuario tiene un fichero particular para la planificación de tareas y que, por otro lado, existe un fichero general /etc/crontab, que en debian es mejor no tocar, porque se ha modularizado la configuración dentro de otros ficheros.

Los ficheros de usuario no es necesario conocer dónde están5. De los ficheros generales, en cambio, si se requiere conocer la organización. Un vistazo dentro de /etc/ nos arrojará estos resultados:

$ cd /etc/ ; ls -1Fd --group-directories-first cron*
cron.d/
cron.daily/
cron.hourly/
cron.monthly/
cron.weekly/
crontab

Se encuentra el fichero general (/etc/crontab) que hemos aconsejado no tocar y una serie de directorios. Dentro del primero (/etc/cron.d) pueden crearse cualesquiera ficheros con la sintaxis que ya hemos descrito (la que incluye la línea que refiere el usuario). Todas las líneas que aparezcan en todos esos ficheros formaran parte de la configuración de cron como si las hubiéramos escrito en el fichero general. El resto de directorios, sin embargo, no deben contener ficheros de este tipo, sino scripts ejecutables. Dependiendo de dónde incluyamos el script se ejecutarán cada hora, cada día, cada semana o cada mes. La hora exacta a la que se ejecutan puede averiguarse consultando el fichero general.

4.2.1.2.3. Definición de tareas

La definición de las tareas periódicas consiste en dotar de contenido a los ficheros ya indicados. Sin embargo, no debe hacerse mediante edición directa, sino a través del comando

crontab

Permite definir las tareas periódicas que se desean ejecutar en el ordenador. Su sintaxis es:

crontab [<opciones>]

Un usuario cualquiera puede editar el fichero así:

$ crontab -e

Si únicamente quiere ver cuál es el contenido de su fichero, basta que use la opción -l:

$ contrab -l

Por último puede eliminarse el fichero con la opción -r:

$ crontab -e

El administrador tiene su propio fichero particular, pero también puede usar crontab para modificar (o listar o borrar) las tareas de otro usuario:

$ crontab -u usuario -e

Para crear tareas generales basta con mover los scripts (o hacer enlaces) dentro uno de los cuatro directorios dedicados a tareas horarias, diarias, semanales o mensuales. Si se desea especificar otra frecuencia, basta con crear un fichero que contenga líneas con la sintaxis descrita y moverlo dentro de /etc/cron.d.

cron, además, permite limitar los usuarios que pueden alterar su planificación. Para ello hay dos, ficheros: /etc/cron.allow que actúa como lista blanca, de manera que, si existe, sólo a los usuarios listados en él se les permite la planificación; y /etc/cron.deny, que actúa como lista negra, de modo que todos los usuarios podrán planificar tareas, excepto los listados en él.

4.2.1.2.4. ¿Qué pasa si el ordenador no está siempre encendido?

cron es un demonio que ejecuta tareas, pero sólo si en el momento de ejecutarlas el ordenador está encendido. Como no tiene memoria ni guarda tareas que no llegó a realizar, si a las 6:25am que es a la hora en que se intentan ejecutar las tareas diarias, el ordenador se encontraba apagado, tales tareas no se llevarán a cabo.

Para suplir esta deficiencia, existe un programa llamado anacron que se encarga de supervisar si cron realizó o no una determinado tareas y, si la respuesta es no, la ejecuta.

anacron tiene su propia configuración, en la que no se entrará: debian está preparada para que anacron controle si cron ha ejecutado las tareas diarias, semanales y mensuales, esto es, los scripts almacenados en /etc/cron.daily, /etc/cron.weekly o /etc/cron.monthly. Cualquier otra tarea quedará fuera de la supervisión de anacron y, por tanto, requirirá una configuración específica.

Por hacer

Explicar cómo configurar anacron.

4.2.1.3. Ejercicios sobre cron y at

  1. Apagar el ordenador dentro de tres horas.

  2. Para que no se quede nunca encendido el ordenador por la tarde (a partir de las 15:00), asegurarse de que se apagará.

  3. Que se actualice la lista de paquetes instalables cada tres horas.

  4. Dentro de seis minutos escribir en el fichero ~/tarea_programada la fecha y hora exactas.

    Nota

    Véase la orden date.

  5. Cada seis minutos escriba en el fichero ~/tarea_periodica la fecha y hora exactas, sin eliminar las escrituras anteriores.

  6. Realizar una copia semanal de seguridad de los directorios de todos los usuarios.

    Nota

    Use tar para generar el fichero.

  7. Ídem, pero la copia no debe realizarse durante los meses de julio y agosto.

  8. Dentro de una semana, eliminar el usuario «caducado».

  9. Dentro de cinco horas, apagar el sistema si no quedan usuarios logueados.

  10. Generar cada hora, la lista de usuarios logueados y almacenarla en /tmp/usuarios_fecha-hora.txt.

  11. Apagar el sistema la próxima media noche.

  12. Actualizar automatizadamente todos los días el sistema con apt.

Notas al pie

1

at asigna el indentificador a la tarea según un contador que almacena en /var/spool/cron/atjobs/.SEQ, de modo que cada vez que se genera una nueva orden diferida, se incrementa el contador que almacena en una unidad. Si quisiéramos resetear el contador, bastaría con escribir en el fichero 00000:

# echo "00000" > /var/spool/cron/atjobs/.SEQ

Eso sí, deberíamos asegurarnos primero de que no hay trabajos pendientes.

2

Estos ficheros de usuario se encuentran ubicados dentro de /var/spool/cron/crontabs.

3

En debian, la configuración general está desdoblada en varios ficheros como se verá un poco más adelante, de modo que no es recomendable modificar este fichero.

4

La información completa de su sintaxis se encuentra en su página de manual:

$ man 5 crontab
5

Aunque el curioso podrá encontrarlos dentro de /var/spool/cron/crontabs/.