Cron: programando tareas

Una de las cosas que siempre me ha gustado de Unix, es lo que siempre reseña Eric S. Raymond a través de la archiconocida filosofía Unix: la interfaz universal son los flujos de texto; y eso posibilita que los comandos se puedan programar en el tiempo y realizar tareas no atendidas que nos faciliten la vida.

La programación de tareas en Unix (y sistemas similares como BSD, Solaris, HP-UX, AIX, Linux, MacOS X, etc.) se basa en un pequeño programa que permanece como demonio en nuestro sistema y mantiene una tabla de ejecución de comandos basados en tiempo y con una granularidad de un minuto. Es decir, no se puede programar una tarea con una exactitud mayor de un minuto (por ejemplo, no se podría decir que algo se ejecute cada 20 ó 30 segundos).

La tabla de tareas programadas (crontab)

En cualquier sistema, si escribimos como cualquier usuario la orden: crontab -e; entraremos inmediatamente en un editor en el que nos debería de mostrar información de la tabla de tareas programadas, o un fichero con un comentario indicando el formato… o en el peor de los casos, un fichero vacío.

Rellenar este fichero es tener en cuenta que los datos debe de estar separados por uno o más espacios, significando cada campo:

  • minutos: el minuto en el que se va a ejecutar el cron.
  • hora: la hora en la que se va a ejecutar el cron.
  • día del mes: día del mes en el que se va a ejecutar el cron.
  • mes: mes en el que se va a ejecutar el cron.
  • día de la semana: día de la semana en que se ejecutará el cron. Este será en formato numérico de 0–7, siendo domingo tanto el cero como el siete.
  • comando: el comando a ejecutar.

Si se configura lo siguiente:

0    5    *    *    *    /home/yo/mi_comando
*/5  *    *    *    *    /home/yo/mi_otro_comando
0,30 *    *    *    *    /home/yo/otro_comando_mas
0    0    *    *    7    /home/yo/dominguete

La primera línea le dice al sistema que se ejecute cuando sean las 5:00h de cada día, y ejecutará mi_comando. La segunda línea hace que mi_otro_comando se ejecute cada 5 minutos. La tercera línea indica que otro_comando_mas debe de ejecutarse en el minuto 00 y 30 de cada hora. Por último, la línea cuatro, hace que la ejecución de dominguete se haga solo el domingo y a las 0:00h.

Cron para administradores

Si estás programando una tarea para que se ejecute de forma recurrente en el sistema, que además requiere de unos permisos especiales o específicos para que se ejecute, es decir, necesita ser un usuario específico o root, entonces debe de programarse dicha tarea en la tabla de crontab del sistema, donde, además de especificar el tiempo, se puede especificar el usuario que la llevará a cabo.

Esto se configura en el fichero /etc/crontab (o en los ficheros fraccionados que puedes encontrar en la mayoría de sistemas en /etc/crontab.d). El usuario aparece como campo antes del comando. Solo hay que indicar el nombre del usuario y listo.

Cron para usuarios

Si tienes un usuario en el sistema y quieres hacer algo como que se ejecute fetchmail cada 15 minutos y rescate el correo de tus cuentas de correo en tu propia cuenta del servidor, tan solo tienes que ejecutar el comando de edición de crontab -e, y poner en el fichero algo como esto:

*/15  *    *    *    *     fetchmail

Con esto, tendremos asegurada la ejecución cada 15 minutos del comando (justamente en los minutos 0, 15, 30 y 45 de cada hora).

Cosas a tener en cuenta

Algunas preguntas que nos pueden asaltar son:

  • ¿Cómo puedo ver los cron que tengo configurados sin editarlos? estos y otros comandos puedes revisarlos a través de man crontab, pero a modo de reseña rápida, sería: crontab -l
  • *Si pongo /7 en la primera hora se ejecuta el cron en los minutos 0, 7, 14, 21, 28, 35, 42, 49, 56, ¿y en la siguiente hora?** Pues en los mismos minutos. El sistema de cron no asegura que algo se ejecute con una distancia exacta de tiempo, de hecho, la sintaxis lo revela, si el minuto es divisible por 7, se ejecuta, sino no.

Si tienes más preguntas del estilo, agrégalas como comentario y las incluiré en este apartado.

Bonus Track: el comando at

Antes de dar por finalizado el artículo… vamos a pensar, ¿qué pasa si quiero programar una tarea para que se ejecute hoy a las 1:30h… pero solo hoy? … o incluso, ¿si quiero que se ejecute dentro de 2 horas? Pues para eso empleamos el comando at.

Por ejemplo, si queremos que se ejecute a las 18:30h del mismo día por la tarde, basta con decir:

$ at 18:30
at> fetchmail
at> <EOT>
job 1 at Fri Nov 25 18:30:00 2011

Ten presente que se debe de presionar Ctrl+D para finalizar (). Podemos ver el comando en la cola con el comando atq, o incluso eliminarlo con el comando atrm.

Para programar un comando dentro de 2 horas, sería:

$ at now + 2 hours
at> fetchmail
at> <EOT>
job 1 at Fri Nov 25 9:05:00 2011

Con lo que el comando se ejecutaría en dos horas, a contar desde que se lanzó el comando.

También se permite programar la tarea lanzando la ejecución de un fichero de comandos (shell script), así como una gran flexibilidad de configuración horaria. Todo está aquí: man at.

Conclusiones

La programación de tareas es algo trivial en un equipo informático, para los usuarios de GNU/Linux, sobretodo, cuando quieres que el equipo se apague a una determinada hora, convierta un fichero por la noche cuando ya no usas el equipo y pueda ser saturado sin problemas, o quieras programar limpieza de ficheros de forma periódica, descarga de noticias, etc, etc. es más fácil hacerlo con estos programadores que tener que hacerlo a mano.