Cron & crontab, explicados

Lucain publicó hace ya un tiempo un excelente tutorial sobre cron y crontab que me parece vale la pena compartir. Cron es una suerte de equivalente a Tareas Programadas en Windows, sólo que se maneja desde el terminal. Aquellos que prefieran una interfaz visual para lograr el mismo objetivo, pueden ver este otro artículo.

¿Qué es cron?

El nombre cron viene del griego chronos que significa “tiempo”. En el sistema operativo Unix, cron es un administrador regular de procesos en segundo plano (demonio) que ejecuta procesos o guiones a intervalos regulares (por ejemplo, cada minuto, día, semana o mes). Los procesos que deben ejecutarse y la hora en la que deben hacerlo se especifican en el fichero crontab.

Cómo funciona

El demonio cron inicia de /etc/rc.d/ o /etc/init.d dependiendo de la distribucion. Cron se ejecuta en el background, revisa cada minuto la tabla de tareas crontab /etc/crontab o en /var/spool/cron en búsqueda de tareas que se deban cumplir. Como usuario podemos agregar comandos o scripts con tareas a cron para automatizar algunos procesos. Esto es util por ejemplo para automatizar la actualizacion de un sistema o un buen sistema de respaldos.

¿Qué es Crontab?

Crontab es un simple archivo de texto que guarda una lista de comandos a ejecutar en un tiempo especificado por el usuario. Crontab verificará la fecha y hora en que se debe ejecutar el script o el comando, los permisos de ejecución y lo realizará en el background. Cada usuario puede tener su propio archivo crontab, de hecho el /etc/crontab se asume que es el archivo crontab del usuario root, cuando los usuarios normales (e incluso root) desean generar su propio archivo de crontab, entonces utilizaremos el comando crontab.

Crontab es la manera mas sencilla de administrar tareas de cron en sistemas multiusuario, ya sea como simple usuario de sistema o usuario root.

Utilizando crontab

Vamos empezando con un ejemplo simple.

Vamos a automatizar la actualización de un sistema, para eliminar la molesta de “siempre tengo que andar actualizando y eso no me gusta!”.

Primero que nada haremos un script. Este script será llamado por cron y contendrá todas las instrucciones que queremos que haga, por lo tanto es necesario probarlo en varios casos y de varias formas antes de incluirlo a cron, un sencillo script de actualizacion como este:

#!/bin/bash
#script ejemplo de actualizacion
#elija su distribucion
#debian-ubuntu
#apt-get update & apt-get -y upgrade
#fedora
#yum -y update
#Arch
#pacman --noconfirm -Syu

Quitale el # a la línea de tu distro. En caso de que sea Ubuntu/Debian, a la que empieza  con apt-get.

Guardamos el script como actualizacion.sh (ej. directorio scripts tu home). Cambiamos los permisos de ejecucion del dichoso script con:

chmod a+x ~/scripts/actualizacion.sh

Ejecutamos el script un par de veces para verificar que todo ejecute sin problemas, modificamos lo necesario (no debe contener errores, si no cron solo repetira un error una y otra vez). Ahora a agregar la tarea a nuestro crontab.

Agregar tareas a crontab

Ejecutamos la edición del crontab con crontab -e, en algunas distros (como ubuntu) nos da la opcion de elegir el editor de textos que deseemos, los demás nos quedamos con vi. El archivo crontab lucirá algo asi.

# m h dom mon dow user command

donde:

  • m corresponde al minuto en que se va a ejecutar el script, el valor va de 0 a 59
  • h la hora exacta, se maneja el formato de 24 horas, los valores van de 0 a 23, siendo 0 las 12:00 de la medianoche.
  • dom hace referencia al día del mes, por ejemplo se puede especificar 15 si se quiere ejecutar cada dia 15
  • dow significa el día de la semana, puede ser numérico (0 a 7, donde 0 y 7 son domingo) o las 3 primeras letras del día en inglés: mon, tue, wed, thu, fri, sat, sun.
  • user define el usuario que va a ejecutar el comando, puede ser root, u otro usuario diferente siempre y cuando tenga permisos de ejecución del script.
  • command refiere al comando o a la ruta absoluta del script a ejecutar, ejemplo: /home/usuario/scripts/actualizar.sh, si acaso llama a un script este debe ser ejecutable

Para que quedara claro unos cuantos ejemplos de tareas de cron explicados:

15 10 * * * usuario /home/usuario/scripts/actualizar.sh

Ejecutará el script actualizar.sh a las 10:15 a.m. todos los días

15 22 * * * usuario /home/usuario/scripts/actualizar.sh

Ejecutará el script actualizar.sh a las 10:15 p.m. todos los días

00 10 * * 0 root apt-get -y update Usuario root

Ejecutará una actualización todos los domingos a las 10:00 a.m

45 10 * * sun root apt-get -y update

Usuario root ejecutará una actualización todos los domingos (sun) a las 10:45 a.m

30 7 20 11 * usuario /home/usuario/scripts/actualizar.sh

El día 20 de noviembre a las 7:30 el usuario correra el script

30 7 11 11 sun usuario /home/usuario/scripts/pastel_con_velitas.sh

El día 11 de noviembre a las 7:30 a.m. y que sea domingo, el usuario festejará su sysadmin (o sea a mí)

01 * * * * usuario /home/usuario/scripts/molestorecordatorio.sh

Un molesto recordatorio cada minuto de cada hora todos los días (NO recomendable).

Igual se pueden manejar rangos especiales:

30 17 * * 1,2,3,4,5

A las 5:30 de la tarde todos los días de lunes a viernes.

00 12 1,15,28 * *

A las 12 del día todos los días primero, quince y 28 de cada mes (ideal para nóminas)

Si esto resulta confuso, crontab maneja cadenas especiales para definir estos rangos.

@reboot Ejecuta una vez, al inicio
@yearly ejecuta sólo una vez al año: 0 0 1 1 *
@annually igual que @yearly
@monthly ejecuta una vez al mes, el día primero: 0 0 1 * *
@weekly Semanal el primer minuto de la primer hora de la semana. 0 0 * * 0″.
@daily diario, a las 12:00A.M. 0 0 * * *
@midnight igual que @daily
@hourly al primer minuto de cada hora: 0 * * * *

Su uso es muy sencillo.

@hourly usuario /home/usuario/scripts/molestorecordatorio.sh
@monthly usuario /home/usuario/scripts/respaldo.sh
@daily root apt-get update && apt-get -y upgrade

Por último y no menos importante:

Administracion de trabajos en cron

crontab archivo

Remplaza el existente archivo crontab con un archivo definido por el usuario

crontab -e

Editar el archivo crontab del usuario, cada linea nueva sera una nueva tarea de crontab.

crontab -l

Lista todas las tareas de crontab del usuario

crontab -d

Borra el crontab del usuario

crontab -c dir

Define el directoriod e crontab del usuario (este debe tener permisos de escritura y ejecucion del usuario)

crontab -u usuario

prefijo para manejar el crontab de otro usuario, ejemplos:

$ sudo crontab -l -u root
$ sudo crontab -e usuario2
#crontab -d -u usuario

Esta herramienta, como muchas otras se pueden ver a mas profundidad y con mas detalle en:

¡Gracias Lucain!

45 comentarios

  1.   tonic dijo

    falta el */30 (en el campo de los minutos) que ejecuta cada 30 minutos…

    1.    erm3nda dijo

      Justo esto iba a comentar yo hasta que decidí revisar los comentarios 😀
      Es un dato muy importante y algo muy útil este modificador.

      1.    KIKA dijo

        Hola!
        En este momento estoy probando una configuración cada 45 minutos.

        */45 * * * *, y la instrucción se ejecuta a los 45 minutos de cada hora Y cada hora. Es decir:

        Se ejecuta a las 3:45, luego a las 4:00, 4:45, luego a las 5:00, 5:45, 6:00, 6:45, y así sucesivamente.

        Tengo algo mal?, qué puedo hacer para que sea sólo cada 45 minutos, o por lo menos una sola vez a las y 45 de cada hora.

    2.    KIKA dijo

      Hola!
      En este momento estoy probando una configuración cada 45 minutos.

      */45 * * * *, y la instrucción se ejecuta a los 45 minutos de cada hora Y cada hora. Es decir:

      Se ejecuta a las 3:45, luego a las 4:00, 4:45, luego a las 5:00, 5:45, 6:00, 6:45, y así sucesivamente.

      Tengo algo mal?, qué puedo hacer para que sea sólo cada 45 minutos, o por lo menos una sola vez a las y 45 de cada hora.

  2.   Slack dijo

    Hola super util la información par aclarar como funciona cron.
    Bytes

  3.   Slack dijo

    para *

  4.   Alvaro Ortiz dijo

    Uf… un poco lioso.

  5.   Cazador dijo

    Excelente, gracias por aclararme como funciona cron.. vamos a meter un poco de mano 🙂

  6.   Jacob dijo

    Esta línea según entiendo se ejecutara a las 10 :15 p.m corríjanme si me equivoco
    pues ahi dice 10:15 a.m
    15 22 * * * usuario /home/usuario/scripts/actualizar.sh

  7.   Agustin dijo

    Hola! muy buena info.
    para ejecutar un Script cada media hora la linea que habria que agregar a CronTab seria: “30 * * * * root Scrip.sh” Correcto? Muchas Gracias!

  8.   usemoslinux dijo

    No. Si mal no recuerdo, para eso tenés que poner /30 * * * * root Scrip.sh.
    O sea, agregar la / antes del 30.
    Saludos! Pablo.

  9.   Jonathan dijo

    Hola me gusto tu post, esta muy completo pero queria preguntarte algo.
    Estoy teniendo problemas con este comando y uno parecido “at”.

    Quiero ejecutar un script a una hora determinada y pongo

    at -f /home/mi_user/Escritorio/script.sh 18:08 ejemplo

    y no se ejecuta el script en pantalla osea en la terminal, se ejecuta en 2do plano?

    Y con cron me pasa lo mismo, edito el archivo crontab con “crontab -e”

    al final le agrego esta linea:

    46 19 mi_user /home/mi_user/Escritorio/script.sh

    y no hace nada, no muestra el script.

    Alguna sugerencia? Muchas gracias y disculpa las molestias

    1.    usemoslinux dijo

      Para que te aparezca el terminal, tal vez tengas que ejecutar el terminal y pasar como parámetro el script.

      Por ejemplo:

      lxterminal -e “mi_user /home/mi_user/Escritorio/script.sh”

      El parámetro a utilizar puede variar en base al emulador de terminal que utilices.

      Espero que sirva.

      Abrazo! Pablo.

  10.   patretcas dijo

    Se agradece el aporte.

    10 puntos !!

    salu2 !!

  11.   Rodolfo dijo

    Muchas gracias, me sirvió mucho para aclarar algunas cosas, gracias totales, para más detalles o dudas iré a la PAGINA MAN, saludos reiterados.

  12.   jahir dijo

    tio muchas gracias, he ido leyendo y probando los ejemplos. muchas gracias… es muy entendible. Saludos

  13.   Geovanni dijo

    Yo utilizó ubuntu Server 12.04.2 LTS, y la version de crontab que tengo, para borrar la lista de trabajos del usuario se utiliza, crontab -r (y -l, como dice este manual). Seguro es por cuestion de versiones.

    Por otro lado, yo en alguna vez ejecute solo crontab y esto como que me dejo crear mi propio archivo de ejecución, pero este no era el que se estaba ejecutando. El que se ejecuta es el que esta en /etc/crontab. quizas a alguien le sirva el comentario.

    P.D. (yo busque con locate y whereis crontab pero solo me devolvia la direccion antes mencionada y otro archivo que esta encriptado, entonces si el que se ejecutaba era el de /etc/crontab, pero al ejecutar el comando crontab -e me aparecia el mio con todos los trabajos que segun yo habia definido) donde se estaba almacenando este archivo’???? saludos. Siempre me logueo con root.

  14.   Sebastian dijo

    Excelente, muy util!!!

  15.   mmm dijo

    Hola, quisiera hacer esto………… “15 10 * * * root ifdown eth0”

    es decir que a cierta hora se apague la tarjeta de red………… pues bien, lo puse en el crontab y no funcinó…….. qué onda??

    Saludos y gracias

  16.   Miguel dijo

    Te faltó definir “mon” después del título “Agregar tareas al crontab”

    Igual está bonito el artículo, cron es sumamente útil.

  17.   OScar dijo

    Que chevere me sirvio mucho buen post pregunta
    ¿Si quiero hacer seguimiento a los registros que deja la ejecuciòn de tareas donde lo puedo visualizar?

    es decdir quiero ver el historial de las acciones hechas en el pasado de este archivo y quiero ver quien lo ha modificado y la fecha

    gracias

  18.   oscar dijo

    quier verificar el historial de modificacion de este

    como lo puedo hacer

    gracias

  19.   Andrés Ledo dijo

    Buenos días,

    Creo que en el script de ubuntu te has equivocado, has puesto ap-get -y upgrade en vez de apt-get -y upgrade. (Te has dejado una t).

    Un saludo.

    1.    usemoslinux dijo

      Así es. Gracias!
      Abrazo! Pablo

  20.   Gabriel dijo

    Quiero saber como crear un archivo cron para poder especificar el tiempo cada cuando se ejecuta , el directorio, etc.

  21.   Valentin dijo

    Gracias por aclarar el funcionamiento y los comandos basicos para cron, ahora a entretenerse un rrato .-

  22.   Sander dijo

    Siempre que busco información de cualquier tema relacionado a Gnu/Linux doy vueltas y vueltas para al final siempre encontrar en el 90% de los casos el mejor tutorial en esta genial comunidad, creo que desde ahora empezaré acá y luego por otros lados.

    Saludos

    1.    usemoslinux dijo

      Gracias Sander! Un abrazo! Pablo.

  23.   daryo dijo

    dom = day of month
    dow= day of week
    es mas facil si se asocia

  24.   Pascual dijo

    Muchas gracias muy completo esto y bien explicado.

  25.   Maxillia dijo

    Esto es lo mismo que nos dio mi profesor de Sistemas Operativos no le cambio nada, ahora veo por que es tan mala la clase .-., bueno esto mismo da re de tarea xD

  26.   Marcelo dijo

    Estimado,

    Consulta, se puede limitar el tiempo de duración de una tarea ?.
    Por ejemplo tengo una tarea que se repite cada 5 minutos, en la repetición si todavía está activa dicha tarea, que la mate y vuelva a ejecutarse.

    Gracias,
    Marcelo.-

    1.    usemoslinux dijo

      Hola Marcelo!

      Creo que sería mejor que plantees esta consulta en nuestro servicio de preguntas y respuestas llamado Ask DesdeLinux a fin de que toda la comunidad pueda ayudarte con tu problema.

      Un abrazo, Pablo.

  27.   aj dijo

    buen post.
    Cuál es el comando por terminal para agregar tareas al crontab (sin entrar al crontab y agregarlas manualmente con ‘crontab -e’ o reemplazar el crontab por otro crontab con ‘crontab archivo’).
    La idea es crear un script externo para agregarle las tareas al crontab
    Gracias

    1.    david dijo

      me parece que podrias usar “echo ‘lo que quieras agregar’ | cat >> ‘ruta del cronotab(/etc/cronotab)’ “

  28.   Rafael Vera dijo

    como seria una expresion que se ejecute cada 3 dias exactos

  29.   José Antonio dijo

    Hola.

    Tengo un problema al ejecutar una tarea del cron.

    Yo ejecuto la siguiente tarea con cronta -e:

    01 * * * * root /home/user/script/mifichero.sh

    pero la tarea no se realiza. He comprabado que mifichero.sh tenga permiso de ejecución y que el usuario que la ejecute sea root.

    La misma tarea ejecuto en /etc/crontab y tras el reinicio del servicio, tampoco me funciona.
    El contenido de mifichero.sh es un comando que actualiza una BBDD y que si lo ejecuto en consola si funciona.
    alguna idea de cual puede ser el problema?

    1.    Fredd dijo

      Es probable que el usuario de base de datos no tenga todos los permisos y primero tengas que exportar las variables de entorno de tu motor de base de datos.
      Por ejemplo en db2, esta línea iría al comienzo del script
      . /home/db2inst1/sqllib/db2profile

      Otra causa podría ser que el script requiera conexión a la base de datos, realiza la conexión a la base dentro del script

  30.   LA3 dijo

    no sabia que habia que reiniciar el crond, llevaba un rato peleándome con esto

  31.   kenia dijo

    sabran como indicar que la tarea se corra todos los fines de mes , a la hora que se le indique.. el detalle es que no logro como sepa que tome el ultimo dia de cada mes..??? tuve que anotarlos uno a uno pero cuando viene fin de mes de febrero que es biciesto se me complica ..

  32.   Jesus dijo

    buen dia!!

    como detengo el proseso que se esta ejecutando en el crontab?

  33.   Jesus dijo

    proceso* …………

  34.   Julianna dijo

    serб que vc pode me ajudar? eu tenho um script de minha autoria que nгo funciona no crontab! jб dei todas as permissхes, no prуprio cron especifico o usuбrio que pode executб-lo mas nada acontece! Gostaria de saber se vc pode me ajudar, pois outras coisas funcionam no cron! Vlws

  35.   Antox dijo

    como pondrías una tarea para que se ejecuta cada ultimo día de mes (dias: 31-30-28)?

  36.   tfercho dijo

    Como ya saben el comando su se usa para cambiar de usuario en una consola. Si yo uso el comando su asi: “su usuario” cambio de usuario pero sin las configuraciones propias de “usuario”, si yo ejecuto su as: “su – usaurio” cambia de usuario cargando las configuraciones del usuario. Con cron indico el usuario, pero como cargo las configuraciones de este usuario?

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *