Base de conocimientos · Linux
Configuración de tareas cron
Última actualización: 2020-01-18
Compruebe que dispone de una cuenta de correo electrónico válida para recibir los mensajes. Lea el siguiente artículo sobre la "configuración de Cron Jobs" y, si aún necesita ayuda, abra un ticket de soporte.
Cron es un aspecto comúnmente confuso y malconfigurado del sistema operativo. Técnicamente, el cron es sólo el daemon del reloj (/usr/sbin/cron o tal vez /usr/sbin/crond) que ejecuta comandos en momentos específicos. Sin embargo, un puñado de archivos de configuración y programas van a inventar el paquete cron. Como muchos procesos del sistema, el cron nunca termina. Los archivos controladores para cron son las tablas de cron o crontabs. Los crontabs se encuentran a menudo en /var/spool/cron/crontab. Sin embargo, en SuSE los encontrará en /var/spool/cron/tabs. Los nombres de los archivos en este directorio son los nombres de los usuarios que envían los trabajos de cron.
A diferencia de otras variantes de UNIX, el demonio cron de Linux no permanece inactivo hasta que la siguiente tarea cron esté lista. En su lugar, cuando cron termina una tarea, sigue comprobando una vez por minuto si hay más tareas que ejecutar. Además, no debe editar los archivos directamente. Puede editarlos con un editor de texto como vi, aunque existe el riesgo de causar errores. Por lo tanto, debe utilizar la herramienta que proporciona Linux: crontab. (consulte la página del manual para obtener más información)
La utilidad crontab tiene varias funciones. Es el medio por el cual se envían al sistema los archivos que contienen las tareas cron. En segundo lugar, puede mostrar el contenido de su crontab. Si usted es root, también puede enviar y mostrar las tareas de cualquier usuario. El problema es que las tareas no pueden enviarse de forma individual. Con crontab, debe enviar todas las tareas al mismo tiempo.
Al principio, esto puede parecer algo molesto. Sin embargo, veamos el proceso de "añadir" una tarea. Para añadir una tarea cron, primero debe mostrar el contenido del crontab existente con la opción -l. Si usted es root y desea añadir algo al crontab de otro usuario, utilice la opción -u seguida del nombre de inicio de sesión del usuario. A continuación, redirija este crontab a un archivo, que después podrá editar. (Tenga en cuenta que en algunos sistemas crontab dispone de la opción -e, de "edit" (editar), que hace todo el trabajo por usted. Consulte la página del manual para obtener más información.)
Por ejemplo, supongamos que usted es el usuario root y desea añadir algo al crontab del usuario UUCP. Primero, obtenga la salida de la entrada de crontab existente con este comando:
crontab -l -u uucp >/tmp/crontab.uucp
Para añadir una entrada, simplemente incluya una nueva línea. Guarde el archivo, cierre el editor y ejecute de nuevo la utilidad crontab. Esta vez, omita la opción -l, que sirve para mostrar el archivo, e incluya el nombre del archivo. La utilidad crontab también puede aceptar datos de stdin, por lo que podría omitir el nombre del archivo y crontab le permitiría introducir las tareas cron en la línea de comandos. Tenga presente que cualquier crontab anterior se elimina, sea cual sea el método que utilice.
El archivo /tmp/crontab.uucp ahora contiene el contenido de UUCPs crontab. Puede parecer algo así:
39,9 * * * * /usr/lib/uucp/uudemon.hour > /dev/null
10 * * * * /usr/lib/uucp/uudemon.poll > /dev/null
45 23 * * * ulimit 5000; /usr/lib/uucp/uudemon.clean > /dev/null
48 10,14 * * 1-5 /usr/lib/uucp/uudemon.admin > /dev/null
A pesar de su apariencia, cada entrada de crontab consta de solo seis campos. Los cinco primeros representan la hora a la que debe ejecutarse la tarea y el sexto es el comando propiamente dicho. Los cinco primeros campos se separan mediante un espacio o un tabulador y representan, respectivamente, las siguientes unidades:
minutos (0-59)
hora (0-23)
día del mes (1-31)
mes del año (1-12)
día de la semana (0-6, 0=domingo)
Para especificar todos los valores posibles, utilice un asterisco (*). Puede especificar un único valor simplemente incluyéndolo. Por ejemplo, la segunda línea del ejemplo anterior tiene el valor 10 en el primer campo, lo que significa 10 minutos después de la hora en punto. Como los otros cuatro campos de tiempo son asteriscos, esto significa que el comando se ejecuta cada hora de todos los días, 10 minutos después de la hora en punto.
Los intervalos de valores se componen del primer valor, un guion y el valor final. Por ejemplo, la cuarta línea tiene un intervalo (1-5) en la columna del día de la semana, lo que significa que el comando solo se ejecuta los días 1 a 5, de lunes a viernes.
Para especificar valores distintos que no se encuentran dentro de un intervalo, separe los valores individuales con una coma. En el cuarto ejemplo, el campo de la hora tiene los dos valores 10 y 14. Esto significa que el comando se ejecuta a las 10 a. m. y a las 2 p. m.
Tenga en cuenta que los tiempos son aditivos. Veamos un ejemplo:
10 * 1,16 * 1-5 /usr/local/bin/command
El comando se ejecuta 10 minutos después de cada hora los días uno y dieciséis, así como de lunes a viernes. Si el día uno o el dieciséis cayeran en fin de semana, el comando se ejecutaría igualmente, porque se aplicaría el campo del día del mes. Sin embargo, esto no significa que, si el día uno es lunes, el comando se ejecute dos veces.
La entrada de crontab puede definirse para ejecutarse en intervalos distintos de cada hora o cada día. La granularidad puede especificarse, por ejemplo, cada dos minutos o cada tres horas, sin tener que incluir cada entrada individual en el crontab.
Supongamos que queremos ejecutar el comando anterior no a los 10 minutos de cada hora, sino cada diez minutos. Podríamos crear una entrada como la siguiente:
0,10,20,30,40,50 * 1,16 * 1-5 /usr/local/bin/command
Esto se ejecuta cada 10 minutos: en punto, 10 minutos después, 20 minutos después, y así sucesivamente. Para facilitar las cosas, podríamos crear la entrada de esta otra forma:
*/10 * 1,16 * 1-5 /usr/local/bin/command
Es posible que esta sintaxis resulte nueva para algunos administradores. (A mí me lo resultó.) La barra diagonal (/) indica que, dentro del intervalo especificado (en este caso, cada minuto), el comando se ejecute cada cierto número de minutos; en este caso, cada 10 minutos.
También podemos utilizarla cuando especificamos un intervalo. Por ejemplo, si la tarea solo debiera ejecutarse entre los 20 y los 40 minutos de cada hora, la entrada podría ser así:
20-40 * 1,16 * 1-5 /usr/local/bin/command
¿Y si quisiera que se ejecutara en esos momentos, pero solo cada tres minutos? La línea podría ser así:
20-40/3 * 1,16 * 1-5 /usr/local/bin/command
Para complicar aún más las cosas, podría indicar que desea que el comando se ejecute cada dos minutos entre la hora en punto y los 20 minutos siguientes, cada tres minutos entre los minutos 20 y 40, y después cada 5 minutos entre el minuto 40 y la hora en punto.
0-20/2,21-40/3,41-59/5 * 1,16 * 1-5 /usr/local/bin/command
Una característica muy útil de muchos dialectos de Linux es que permiten especificar abreviaturas para los días de la semana y los meses. Es mucho más fácil recordar que fri corresponde a viernes (Friday) que recordar el 5.
Con excepción de ciertos errores en los campos de tiempo, los errores no se notifican hasta que cron ejecuta el comando. Todos los mensajes de error y la salida se envían por correo a los usuarios. Al menos eso es lo que indica la página del manual de crontab, y en esencia es cierto. Sin embargo, como se ve en los ejemplos anteriores, usted está redirigiendo stdout a /dev/null. Si lo desea, también podría redirigir stderr allí, y nunca vería si se produjo algún error.
La salida se envía por correo al usuario porque no existe un terminal real en el que se ejecuten los cronjobs. Por lo tanto, no hay pantalla donde mostrar los errores. Tampoco hay teclado para recibir datos de entrada. ¿Significa eso que no se puede proporcionar entrada a una tarea de cron? No. Recuerde lo visto sobre los scripts de shell. Podemos redefinir stdin, stdout y stderr. De este modo, todos pueden apuntar a archivos y comportarse como esperamos.
Quiero señalar que no recomiendo realizar redirecciones en el campo de comando del crontab. Prefiero hacer allí lo mínimo posible. En su lugar, indico la ruta absoluta de un script de shell. Así puedo probar la entrada del crontab con algo sencillo. Una vez que funciona, puedo modificar el script de shell sin tener que volver a enviar el cronjob.
Tenga en cuenta que cron no es exacto. Se sincroniza al comienzo de cada minuto. En un sistema muy ocupado en el que se pierden ciclos de reloj, es posible que las tareas no se ejecuten hasta un par de minutos después de la hora programada. Además, puede haber otros procesos con mayor prioridad que retrasen las tareas de cron. En algunos casos (en particular en sistemas muy ocupados), es posible que se omitan tareas si se ejecutan cada minuto.
El acceso al servicio cron se controla mediante dos archivos, ambos en /etc. Si existe el archivo cron.allow, puede especificar qué usuarios pueden utilizar cron. El archivo cron.deny indica qué usuarios no tienen permitido utilizar cron. Si no existe ninguno de los dos archivos, solo los usuarios del sistema tienen acceso. No obstante, si desea que todos tengan acceso, cree un archivo cron.deny vacío. En otras palabras, a nadie se le deniega el acceso.
A menudo es útil para root ejecutar trabajos como usuario diferente sin tener que cambiar usuarios (por ejemplo, usando el comando su). La mayoría de los dialectos de Linux proporcionan un mecanismo en forma de archivo /etc/crontab. Este archivo es normalmente sólo comprimible por root y en algunos casos, sólo root puede leerlo (que a menudo es necesario en entornos de alta seguridad). La sintaxis general es la misma que los crontabs estándar, con un par de excepciones.
La primera diferencia es el encabezado, que puede ver aquí:
SHELL=/bin/sh
PATH=/usr/bin:/usr/sbin:/sbin:/bin:/usr/lib/news/bin
MAILTO=root
#
# check scripts in cron.hourly, cron.daily, cron.weekly, and cron.monthly
#
59 * * * * root rm -f /var/spool/cron/lastrun/cron.hourly
14 0 * * * root rm -f /var/spool/cron/lastrun/cron.daily
29 0 * * 6 root rm -f /var/spool/cron/lastrun/cron.weekly
44 0 1 * * root rm -f /var/spool/cron/lastrun/cron.monthly
La variable SHELL define el shell con el que se ejecutará cada comando. La variable PATH es como la variable de entorno PATH habitual y define la ruta de búsqueda. La variable MAILTO indica quién debe recibir los mensajes de correo electrónico, que incluyen los mensajes de error y la salida estándar de los comandos ejecutados.
La estructura de las entradas reales es prácticamente igual con la excepción del nombre de usuario (root en cada caso aquí). De esta manera, los usuarios de raíz (o quien pueda editar /etc/crontab) pueden definir qué usuario ejecuta el comando. Tenga en cuenta que esto puede ser un gran agujero de seguridad. Si alguien puede escribir a este archivo, puede crear una entrada que funciona como raíz y por lo tanto tiene control completo del sistema.
El siguiente comando de la «suite» de cron es at. Su función es ejecutar un comando a una hora específica. La diferencia es que, una vez ejecutada la tarea de at, esta desaparece del sistema. Al igual que con cron, dos archivos, at.allow y at.deny, tienen el mismo efecto sobre el programa at.
El comando batch también se utiliza para ejecutar comandos una sola vez. Sin embargo, los comandos enviados con batch se ejecutan cuando el sistema puede hacerlo, es decir, cuando tiene menos carga, por ejemplo, en plena noche. Es posible que dichas tareas se distribuyan a lo largo de todo el día, según la carga del sistema.
Un aspecto que conviene destacar es el comportamiento de at y batch. Ambos aceptan los nombres de los comandos desde la línea de comandos y no como argumentos del propio comando. Primero debe ejecutar el comando para pasar a una nueva línea, donde introduce los comandos que desea ejecutar. Después de cada comando, pulse Enter. Cuando termine, pulse Ctrl-D.
Dado que estos dos comandos aceptan comandos desde stdin, puede introducirlos sin tener que hacerlo en una línea nueva cada vez. Una posibilidad es redirigir la entrada desde un archivo. Por ejemplo:
at now +1 hour < command_list
donde command_list es un archivo que contiene una lista de comandos. También podría usar at (o batch) al final de una canalización
cat command_list | at now + 1 hour
cat command_list | batch
Otra cosa interesante tanto en el lote como en el lote es que crean una especie de script de shell para ejecutar su comando. Cuando se ejecuta en o lote, se crea un archivo en /usr/spool/cron/atjobs. Este archivo contiene las variables del sistema que normalmente habría definido, más alguna otra información que está contenida en /usr/lib/cron.proto. Esto crea esencialmente un ambiente como si hubieras iniciado sesión.
Tell us what you need
Compare available plans or describe your workload so we can discuss a suitable starting point.