Saltar la navegación

El servicio cron para programación de tareas

Cron es un servicio (demonio) que ejecuta tareas programadas. Permite que tanto el root como el resto de los usuarios puedan ejecutar comandos o scripts a intervalos regulares a una hora y/o fecha determinada, por ejemplo, un comando podría ejecutarse cada cinco minutos, diariamente, todos los martes a las diez de la mañana, etc. Es muy habitual utilizarlo en el contexto de la administración de sistemas para realizar tareas desatendidas como copias de seguridad, captura de datos del estado del sistema para una posterior estadística, etc.

Existen varias implementaciones de cron, como cronie, dcron (el cron de Dillon), fcron, bcron o el vixie-cron que es el más extendido y el que veremos en Debian, aunque son muy similares.

El Vixie Cron se utiliza en prácticamente todas las implementaciones de GNU/Linux y fue desarrollado por una de las personas más importantes del mundo Unix, Paul Vixie.

En Debian el paquete que lo contiene se denomina cron y se instala de forma automática con la instalación del sistema operativo.

Cron se lanza automáticamente al arrancar el sistema a través del demonio init, usando el script /etc/init.d/cron, o el demonio systemd, usando la unidad de servicio cron.service, esto dependerá del tipo de arranque que tenga el sistema. También puede usarse el comando service independientemente del tipo de arranque.

# /etc/init.d/cron 
[info] Usage: /etc/init.d/cron {start|stop|status|restart|reload|force-reload}.
# systemctl status cron.service 
# service cron status
● cron.service - Regular background program processing daemon
   Loaded: loaded (/lib/systemd/system/cron.service; enabled)
   Active: active (running) since dom 2015-12-05 08:43:57 CET; 1h 1min ago
     Docs: man:cron(8)
 Main PID: 552 (cron)
   CGroup: /system.slice/cron.service
           └─552 /usr/sbin/cron -f

Un fichero crontab es un fichero de texto donde se dan las instrucciones para que cron ejecute las tareas programadas. Cron al iniciarse, lee ficheros de este tipo en varios sitios, los carga en memoria y a partir de ahí, cada minuto comprueba si tiene que ejecutar alguna tarea.

En primer lugar, cron busca ficheros crontab en /var/spool/cron/crontabs, donde cada usuario podrá tener un único fichero con sus tareas programadas, estos ficheros no deberían ser modificados directamente, sino a través del comando crontab, como veremos más adelante. Y en segundo lugar, se miran las tareas programadas por el root para el sistema, las cuales deben estar en el fichero /etc/crontab o en el directorio /etc/cron.d. Este fichero, particularmente en Debian, contiene de partida las siguientes líneas:

17 *    * * *    root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *    root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6    * * 7    root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6    1 * *    root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )

que sirven para ejecutar cada hora, cada día, cada semana y cada mes, los scripts (con permiso de ejecución) que haya en los directorios /etc/cron.hourly, /etc/cron.daily, cron.weekly y cron.monthly, respectivamente; para cualquier otra periodicidad o incluso si no nos gustan las horas establecidas, tendríamos que añadir la correspondiente línea. El uso principal de estos directorios es para que cuando se instale algún paquete en el sistema, este pueda colocar allí los scripts que necesite ejecutar periódicamente para su correcto funcionamiento, aunque el root, si quiere, también puede utilizarlos.

Cualquier script que se incluya en los cuatro directorios anteriores debe cumplir las siguientes condiciones para que cron lo ejecute:

  • Tener permiso de ejecución.
  • El dueño debe ser el root.
  • El grupo y el resto de los usuarios no deben tener permiso de escritura.
  • Los nombres de los ficheros deben estar compuestos por letras, dígitos, guión bajo ( _ ) y guión (-). Ningún otro carácter está permitido, y si se usara, cron no ejecutaría el script.

En el directorio /etc/cron.d el root puede colocar ficheros crontab, pero Debian aconseja que todas las tareas programadas del sistema las ponga el root en /etc/crontab y este directorio se deje para que las aplicaciones que se intalen y quieran poner una tarea programada con una periodicidad distinta a los cuatro directorios anteriores, cree un fichero crontab con la periodicidad concreta que necesite la aplicación.

Por otro lado, cuando cron detecta un cambio de hora menor a tres horas (horario de verano), lo tiene en cuenta de la mejor forma posible. Las tareas que deben ejecutarse durante una hora que nunca existió, por ejemplo, aquellas programadas para las 2:30, cuando a las 2:00 se pasa directamente a las 3:00, se ejecutarán poco después del cambio de hora, es decir, sobre las 3:00. En el caso inverso, cuando se retrasa la hora, las tareas serán ejecutadas solo una vez en el tramo de las 2:00 a las 3:00, aunque este tramo se repita dos veces.

En el caso de que el cambio de hora sea mayor de tres horas, cron no realizará ninguna acción especial.

Hay que tener cuidado con los cambios horarios si el orden y el tiempo entre ejecuciones de tareas programadas importa, si es necesario, se debería preparar una programación especial para las dos noches problemáticas del año, o si es posible, no utilizar esa franja horaria.

El acceso a cron se puede restringir a ciertos usuarios, para ello podemos crear un archivo de autorización explícita (una lista blanca) denominado /etc/cron.allow, donde indicaremos solo los usuarios autorizados para programar tareas, todos los demás usuarios automáticamente quedarán excluidos de dicha funcionalidad. Y a la inversa, si solo deseamos bloquear unos pocos usuarios problemáticos, podríamos agregar sus nombres de usuario en el archivo de prohibición explícita /etc/cron.deny (una lista negra) y todos los demás usuarios podrán usar cron. Si /etc/cron.deny lo dejamos vacío, todos los usuarios pueden utilizar cron. En el caso de que los dos ficheros anteriores existieran, solo se usaría la lista blanca. Es posible también que no existan ninguno de los dos ficheros, que es la situación inicial de Debian, en este caso, todos los usuarios tienen acceso a cron, pero en otros sistemas es justo lo contrario, ningún usuario tendrá acceso a cron excepto el root.

Por defecto, el servicio cron genera mensajes log en /etc/var/syslog cuando se ejecuta una tarea programada, si queremos cambiar esto, debemos configurarlo en el fichero /etc/default/cron con una línea como esta:

EXTRA_OPTS='-L 5'

Esto hace que cron se ejecute con la opción -L y el valor 5. Este valor es el que indica qué eventos se mandarán al fichero log. El valor del parámetro -L debe ser una suma de los siguientes, cada uno de los cuales selecciona un tipo de información:

  • 1 : Informa del comienzo de una tarea.
  • 2 : Informa del final de una tarea.
  • 4 : Informa de que una tarea ha terminado mal, es decir, su código de salida ha sido distinto de cero.
  • 8 : Informa del PID de cada una de las tareas que cron ejecuta.

El valor 0 hará que no se envíen mensajes a /etc/var/syslog. Para el ejemplo, se mandan mensajes log cuando se ejecuta una tarea y cuando una tarea termina mal.