Usando cronjobs en Linux

jueves 06 enero 2011 | In English

cron es un servicio que nos permite agendar el lanzamiento de programa y scripts. Esto nos permite automatizar la ejecución de diversas tareas en nuestra computadora. cron es lanzado cuando encendemos nuestra computadora y se queda funcionando en el fondo.

Cada minuto cron revisa archivos conocidos como crontabs. Un archivo crontab contiene una lista de instrucciones que cron debe de ejecutar. Una instrucción consiste de un comando y ya sea el tiempo en que dicho comando debe ser ejecutado, o una expresión que cron interpreta y, si el minuto actual coincide con una de estas expresiones, cron lanza el comando correspondiente. Cada usuario en un sistema Linux puede tener su propio archivo crontab.

Los archivos crontab personales que pertenecen a usuarios individuales son manejados por un programa llamado crontab. Mientras que cada usuario puede tener un archivo crontab personal, no todos los usuarios puedes hacer uso de crontab para manipularlo, esto depende de como estén configurados los permisos en el sistema.

Temas
Creando una instrucción de cron
Ejemplos de instrucciones de cron
Utilizando crontab para manejar los archivos crontab personales
El archivo crontab global
Lanzando un programa gráfico con cron
Controlando el acceso al comando crontab
Notas al pie

Creando una instrucción de cron

Como se mencionó previamente, una instrucción de cron consiste de dos partes, el tiempo de ejecución y el comando a ser ejecutado. De estas instrucciones solo el tiempo necesita ser ampliamente explicado, el comando puede ser cualquier comando que un shell de texto puede interpretar.

Podemos especificar el tiempo con ya sea una cadena especial o una expresión de tiempo. La expresión de tiempo tiene el siguiente formato, cada parámetro es separado por un espacio:

minuto hora día_del_mes mes día_de_la_semana

Los siguientes valores numéricos son válidos para cada uno de los campos:

Minuto: Entre 0 y 59
Hora: Entre 0 y 23
Día del mes: Entre 0 y 31
Mes: Entre 0 y 12
Día de la semana: Entre 0 y 7. 0 y 7 equivalen al domingo

Adicionalmente, en los campos mes y día_de_la_semana, podemos usar las tres primera letras del nombre del mes y de los días (en inglés), esto puede ser en mayúsculas o minúsculas. Por lo tanto los valores validos para los días de la semana son: Mon (Lunes), Tue (Martes), Wed (Miércoles), Thu (Jueves), Fri (Viernes), Sat (Sábado), Sun (Domingo); y los valores válidos para los meses son: Jan (Enero), Feb (Febrero), Mar (Marzo), Apr (Abril), May (Mayo), Jun (Junio), Jul (Julio), Aug (Agosto), Sep (Septiembre), Oct (Octubre), Nov (Noviembre), Dec (Diciembre).

Podemos usar un rango de números, separados por un guión medio, por ejemplo, 10-20 en el campo hora representa cada hora desde las 10:00 am hasta las 8:00 pm.

El caracter comodín * funciona como si hubiéramos especificado un rango desde el primero hasta el último valor válido de ese campo en particular; todos y cada uno de los posibles valores son verdaderos. Si utilizamos el caracter comodín en el lugar de los minutos, ejecutaría la instrucción cron cada minuto, si la utilizamos en el campo hora, correríamos el comando cada hora, provisto que el resto del tiempo coincida, por ejemplo, si especificamos 10 en la hora, pero agregamos un asterisco en el campo minuto, correría la instrucción cada minuto entre las 10:00 am y las 10:59 am. Si agregamos un asterisco en el día_del_mes y un asterisco en el día_del_la_semana, esto haría que el comando fuera ejecutado cada día de el o los meses especificados.

Podemos utilizar una lista de números, separados por comas, por ejemplo, 3,5,7,11 en el campo mes representaría Marzo, Mayo, Julio y Noviembre.

Podemos utilizar valores de paso, estos son usados en conjunto con rangos, así como con el caracter comodín *, y especifica números a saltar, por ejemplo, */2 en el valor del mes representaría 2,4,6,8,10,12. Imagínalo como una división, si hay residuo, el número es saltado. Por lo tanto en el ejemplo cualquier minuto impar sería saltado ya que dejaría un residuo, y el comando sería ejecutado cada minuto par.

La hora a la que las tareas son ejecutadas depende del tiempo regional de la computadora.

Además de esto, podemos utilizar las siguientes cadenas especiales en vez de los 5 campos para el tiempo:

@reboot - Corre el comando cuando la computadora es iniciada
@yearly o @annually - Corre el comando una vez al año (0 0 1 1 *)
@monthly - Corre el comando una vez al mes (0 0 1 * *)
@weekly - Corre el comando una vez a la semana (0 0 * * 0)
@daily o @midnight- Corre el comando diariamente (0 0 * * *)
@hourly - Corre el comando cada hora (0 * * * *)

Ejemplos de instrucciones de cron

Cada Lunes a las 3:00am:
0 3 * * Mon /usr/bin/comando parámetros

Cada 5 minutos durante el mes de Diciembre:
*/5 * * Dec * /usr/bin/comando

A las 10:00 am, 2:00 pm y 6:00 pm el 23 de Julio:
0 10,14,18 23 Jul * /usr/bin/comando

Lunes, Miércoles y Viernes a la 1:15 pm:
15 13 * * 1,3,5 /usr/bin/comando

Cada hora todos los sábados de Abril:
0 * * Apr Sat /usr/bin/comando parámetro

Cada 12 horas, siempre:
0 */12 * * * /usr/bin/comando

El primer Miércoles de cada mes:
0 0 1-7 * Wed /usr/bin/comando parámetros

Utilizando crontab para manejar los archivos crontab personales

Cada usuario en el sistema puede tener un archivo crontab personal, pero no cada usuario puede hace uso de crontab para instalar y editar su archivo crontab personal; si el usuario no tiene acceso a crontab, solo el administrador del sistema puede crearlo por él o ella. Los archivos crontab personales son guardados en /var/spool/cron/crontabs, sin embargo, uno no debe de editar manualmente estos archivos, en vez de esto debe permitirle al comando crontab manejar estos archivos.

crontab invoca un editor de texto de nuestra elección para poder escribir nuestras instrucciones para cron; y revisa la integridad de el archivo y lo instala una vez que terminamos de editarlo. Si cometemos un error, crontab nos dará un mensaje de error informativo y nos preguntará si queremos reintentar la edición del archivo.

Antes de usar crontab, necesitamos configurar el editor de texto, hacemos esto definiendo la variable de entorno EDITOR. Voy a configurar nano como el editor de texto preferido, ya que es un editor muy simple de utilizar, pero puedes usar un editor de texto diferente, yo personalmente utilizo Vim. Si estás trabajando en un entorno gráfico puedes configurar un editor de texto gráfico como gedit o kate en lugar de nano.

export EDITOR=nano

Para revisar la variable de entorno puedes usar:

echo $EDITOR

Si quieres configurar este editor como default necesitas agregar este comando export a .bashrc en tu carpeta personal para que sea ejecutado cada vez que abres un Shell. Para hacer esto puedes utilizar:

echo "export EDITOR=nano" >> ~/.bashrc

Ubuntu tiene una nueva utilería para manejar el editor de texto por default, este comando es select-editor. select-editor crea un archivo llamado .select_editor en tu carpeta personal donde guarda el valor configurado. Cuando ejecutamos select-editor se nos presenta una pantalla como esta:

Select an editor.  To change later, run 'select-editor'.

  1. /bin/ed
  2. /bin/nano        <---- easiest
  3. /usr/bin/vim.basic
  4. /usr/bin/vim.gtk
  5. /usr/bin/vim.tiny

Choose 1-5 [2]:

En este menú selecciona la segunda opción. Si la variable de entorno EDITOR está configurada, la selección de select-editor es ignorada.

Una vez que elegimos nuestro editor de texto, podemos editar y crear el archivo crontab personal, para hacer esto usamos el comando:

crontab -e

Esto abrirá el editor seleccionado. Si el archivo no existe, crontab creará un nuevo archivo, esté nuevo archivo podría ya tener comentarios, puedes agregar tantas instrucciones como quieras que ejecute cron. Ya que este es el archivo crontab personal solo necesitas especificar el tiempo seguido por el comando a ser ejecutado.

Para revisar los contenidos de tu archivo crontab personal en cualquier momento puedes usar:

crontab -l

Para borrar tu archivo crontab personal necesitas usar:

crontab -r

Opcionalmente al uso de crontab -e, puedes crear un archivo con instrucciones para cron e instalar este archivo nuevo, esto reemplazará tu archivo crontab actual localizado en /var/spool/cron/crontabs/ con los contenidos de tu archivo seleccionado, para hacer esto necesitas usar:

crontab archivo_con_instrucciones_para_cron.txt

Si tienes privilegios de root puedes editar, revisar y borrar los archivos crontab de otros usuarios utilizando crontab con el parámetro -u seguido por el usuario:

crontab -u juan -e

El archivo crontab global

Hay un archivo crontab global localizado en /etc/crontab, este archivo tiene las particularidades de que no necesita ser instalado con el comando crontab, una vez que es editado los cambios son automáticamente tomados en consideración; y que tiene un campo extra para el usuario en cuyo nombre el comando va a ser ejecutado, haciendo al comando ejecutarse con los privilegios de dicho usuario. Este campo se encuentra entre el tiempo de ejecución y el comando.

Necesitas privilegios de root para editar este archivo, para abrirlo en nuestro editor de texto favorito podemos usar lo siguiente (uso gedit para el ejemplo pero puede ser kate, nano, Vim u otro editor de texto):

sudo gedit /etc/crontab

Los siguientes son algunos ejemplos de instrucciones en el archivo crontab global, en estos ejemplos especifico el usuario antes de el comando:

Cada Lunes a las 3:00am:
0 3 * * Mon root /usr/bin/comando parámetros

Cada 5 minutos durante el mes de Diciembre:
*/5 * * Dec * juan /usr/bin/comando

Cada hora todos los sábados de Abril:
0 * * Apr Sat juan /usr/bin/comando parámetro

Cada 12 horas, siempre:
0 */12 * * * root /usr/bin/comando

Lanzando un programa gráfico con cron

Para hacer esto solo necesitamos configurar la variable de entorno DISPLAY antes de que cron lance el programa, esto es tan simple como agregar:

export DISPLAY=:0 &&

justo antes de el programa que queremos lanzar. El cero representa la primer pantalla que es la pantalla por default, si tienes múltiples pantallas, puedes cambiarlo a :1 o :2.

Por ejemplo, yo descargo y principalmente comparto imágenes de Linux con bittorrent, y mi cliente bittorrent preferido es KTorrent. Pero solo lo tengo funcionando de 10:00 pm a 6:00 am, así que tengo las siguientes entradas en mi archivo crontab personal:

0 22 * * * export DISPLAY=:0 && /usr/bin/ktorrent
0 6 * * * killall ktorrent

Controlando el acceso al comando crontab

Podemos controlar que usuarios tienen acceso al comando crontab haciendo uso de los archivos cron.allow y cron.deny localizados en el directorio /etc. Estos archivos son simplemente listas de usuarios, uno por linea.

Si el archivo /etc/cron.allow existe, entonces solos los usuarios listados en este archivo podrán hacer uso de el comando crontab. Si este archivo existe el archivo /etc/cron.deny es ignorado.

Pero si /etc/cron.allow no existe, y tenemos un archivo /etc/cron.deny, entonces todos los usuarios con excepción de los listados en /etc/cron.deny podrán hacer uso de crontab

Y, si ninguno de estos archivos existe, entonces depende de la configuración del sistema el que todos los usuarios o ningún usuario pueda hacer uso de crontab. El usuario root siempre puede hacer uso de crontab. En sistemas basados en Debian todos los usuarios pueden hacer uso de crontab por default. Este es el caso también en Slackware.

Notas al pie

Yo utilizo la dirección completa al programa que lanzo con cron, pero si el programa se encuentra localizado en /usr/bin esto no es necesario, puedes usar el nombre del programa solo.

Categorías: Comandos, FOSS, Linux