.. _cronat: 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. .. _at: .. index:: at Tareas diferidas ---------------- Para la ejecución de tareas futuras se usa el comando :command:`at`:: at [] 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 :file:`/bin/sh`. Esto es importante, porque en *debian* este intérprete no es :program:`bash`, sino :program:`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: :kbd:`now` Ahora mismo. :kbd:`noon` El próximo mediodía. :kbd:`midnight` La próxima media noche. :kbd:`teatime` las próximas cuatro de la tarde. :kbd:`tomorrow` Mañana a esta misma hora. :kbd:`next week` La próxima semana a esta misma hora. :kbd:`next month` El próximo mes a esta misma hora. :kbd:`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*. :kbd:`Oct 21`, :kbd:`10/21` El próximo 21 de octubre a esta misma hora. :kbd:`Oct 21 2017`, :kbd:`10/21/2017` El 21 de octubre de 2017 a esta misma hora. :kbd:`9am`, :kbd:`9:30am` (formato de 12 horas) Las próximas nueve (y media) de la mañana. :kbd:`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: :kbd:`15:00 next week`: dentro de una semana a las tres de la tarde; :kbd:`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 :command:`atq` se le asigna a esta un identificador\ [#]_, 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: .. index:: atq :command:`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: .. index:: atrm :command:`atrm` Para cancelar un tarea definida (o varias) antes de que se ejecute:: $ atrm 6 1 Eliminamos las tareas *1* y *6*. .. _cron: Planificación periódica de tareas --------------------------------- .. warning:: A partir de *Bookwork*, *Debian* no trae instalado de serie el paquete :deb:`cron`, por lo que lo recomendable para planificar tareas es usar las :ref:`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 :command:`cron`, que requiere configurarse a través de archivos de configuración. Cada usuario dispone del suyo particular\ [#]_ (incluido el propio *root*) y, además, existe otro archivo general :file:`/etc/crontab`\ [#]_. 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\ [#]_. 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 :code:`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 :kbd:`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, :kbd:`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: :kbd:`0-30`, significa cada minutos entre 0 y 30. También es posible indicar cada ciertos minutos con la sintaxis :kbd:`/X`. Por ejemplo, :kbd:`/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 :kbd:`*`, que significa que no se fija ningún valor concreto y que, por tanto, se ejecutará la orden cada minuto. En resumen: * :kbd:`30`: Valor simple: *a las y media*. * :kbd:`15,30`: Varios valores: *a las y cuarto* y *a las y media*. * :kbd:`*`: En cada valor posible, esto es, cada minuto. * :kbd:`15-35`: Rango: entre los quince y los treinta y cinco minutos. * :kbd:`/15`: Cada quince minutos, el rango que se especifique. Por ejemplo, :code:`*/15` cada quince minutos, todo el rango de minutos posible (:code:`0-59`). También pueden mezclarse todas estas notaciones. Por ejemplo :kbd:`0-10/2` equivale a :kbd:`0,2,4,6,8,10`. O bien, :kbd:`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. 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 :file:`/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\ [#]_. De los archivos generales, en cambio, si se requiere conocer la organización. Un vistazo dentro de :file:`/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 (:file:`/etc/crontab`) que hemos aconsejado no tocar y una serie de directorios. Dentro del primero (:file:`/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 :command:`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. 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: .. index:: crontab :command:`crontab` Permite definir las tareas periódicas que se desean ejecutar en el ordenador. Su sintaxis es:: crontab [] 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 :command:`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 :file:`/etc/cron.d`. :command:`cron`, además, permite limitar los usuarios que pueden alterar su planificación. Para ello hay dos, archivos: :file:`/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 :file:`/etc/cron.deny`, que actúa como lista negra, de modo que todos los usuarios podrán planificar tareas, excepto los listados en él. .. _anacron: ¿Qué pasa si el ordenador no está siempre encendido? """""""""""""""""""""""""""""""""""""""""""""""""""" :command:`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 :command:`anacron` que se encarga de supervisar si :command:`cron` realizó o no una determinado tareas y, si la respuesta es no, la ejecuta. :command:`anacron` tiene su propia configuración, en la que no se entrará: *debian* está preparada para que :command:`anacron` controle si :command:`cron` ha ejecutado las tareas diarias, semanales y mensuales, esto es, los *scripts* almacenados en :file:`/etc/cron.daily`, :file:`/etc/cron.weekly` o :file:`/etc/cron.monthly`. Cualquier otra tarea quedará fuera de la supervisión de :command:`anacron` y, por tanto, requirirá una configuración específica. .. todo:: Explicar cómo configurar anacron. .. https://geekytheory.com/programacion-de-tareas-asincronas-en-linux-con-anacron .. _ej-cronat: .. include:: /99.ejercicios/15-cronat.rst .. rubric:: Notas al pie .. [#] :command:`at` asigna el indentificador a la tarea según un contador que almacena en :file:`/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 archivo :kbd:`00000`:: # echo "00000" > /var/spool/cron/atjobs/.SEQ Eso sí, deberíamos asegurarnos primero de que no hay trabajos pendientes. .. [#] Estos archivos de usuario se encuentran ubicados dentro de :file:`/var/spool/cron/crontabs`. .. [#] En *debian*, la configuración general está desdoblada en varios archivos como se verá un poco más adelante, de modo que no es recomendable modificar este archivo. .. [#] La información completa de su sintaxis se encuentra en su página de manual:: $ man 5 crontab .. [#] Aunque el curioso podrá encontrarlos dentro de :file:`/var/spool/cron/crontabs/`.