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 archivo 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 identificador[1], 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

Advertencia

A partir de Bookwork, Debian no trae instalado de serie el paquete cron, por lo que lo recomendable para planificar tareas es usar las unidades Timer de SystemD.

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 archivos de configuración. Cada usuario dispone del suyo particular[2] (incluido el propio root) y, además, existe otro archivo general /etc/crontab[3].

4.2.1.2.1. Sintaxis de los archivos

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

Tales archivos 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 archivos

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

Los archivos de usuario no es necesario conocer dónde están[5]. De los archivos 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 archivo general (/etc/crontab) que hemos aconsejado no tocar y una serie de directorios. Dentro del primero (/etc/cron.d) pueden crearse cualesquiera archivos 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 archivos formaran parte de la configuración de cron como si las hubiéramos escrito en el archivo general. El resto de directorios, sin embargo, no deben contener archivos 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 archivo 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 archivos 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 archivo así:

$ crontab -e

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

$ contrab -l

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

$ crontab -e

El administrador tiene su propio archivo 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 archivo 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, archivos: /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.

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