Expresiones CRON

15
52914

Expresiones CRON.

0. Índice de contenidos.

1. Introducción

A veces nos las hemos visto y nos las hemos deseado para configurar «bien» una tarea programada, os lanzo una pregunta :

¿A cuántos de vosotros os ha salido bien a la primera el configurar la planificación de una tarea?

Si sois de los privilegiados que lo conseguís no me queda otra que daros la enhorabuena ;-), en cambio si pertenecáis al resto
de los mortales, es decir, si habeis tenido que realizar un millón y medio de pruebas cambiando la fecha y hora del sistema/servidor, espero
ayudaros con este tutorial para no tener que dedicar tanto tiempo.

¿Quá es una expresión CRON?

Una expresión CRON es una cadena de texto compuesta por 6 o 7 campos separados por un espacio en blanco que se utiliza para representar
instantes o periodos de tiempo.

Su principal uso recae en la planificación de ejecuciones de procesos / rutinas programadas, por lo que puede tener diferentes usos
dentro del ámbito de la empresa , como por ejemplo : ejecución de procesos batch, envio de newsletters a primera hora de la mañana, etc.

Si alguno es un usuario de Unix seguro que todo esto le suena, ya que cron es una herramienta que siempre ha estado incluida y que por
lo tanto ha tenido una amplia comunidad que lo ha utilizado y probado.En mi caso todavía no conozco a nadie que lo haya utilizado y que
no le haya gustado ;-).

Se que este tipo de expresiones se utilizan en numeros sitios, pero en mi caso particular casi siempre he tenido que utilizarlas con
el framework de Quartz

¿Quá es Quartz?

Quartz es un framework Java para la planificación de tareas, que destaca sobre todo
por su potencia y sencillez,esta potencia le viene dada por sus amplias posibilidades de configuración.

Para introduciros un poco más en Quartz os dire que se basa en tres conceptos :

  • Job : Tarea que se desea ejecutar
  • Trigger : Disparador que le indica la forma en la que se ejecutará el job
  • Scheduler : Responsable de ejecutar las tareas mediante su configuración en los trigger.

Conviene diferencias los tipos de trigger que hay :

  • SimpleTrigger : Disparador que se utiliza para ejecutar tareas en una fecha determinada, una hora, un nº de repeticiones o bien
    un intervalor entre repeticiones.
  • CronTrigger : Disparador más utilizado ya que permite realizar expresiones para referirnos a instantes o periodos de tiempo más complejos

De los dos disparadores anteriores nosotros utilizaremos para nuestras expresiones CRON los del tipo CronTrigger.

Si quereis saber más sobre este framework os aconsejo visitar el siguiente tutorial que ha sido realizado por mi compañero
Carlos García Perez : Planificación de tareas en Java mediante Quartz

El objetivo de este tutorial es enseñaros a definir bien vuestras expresiones CRON con independencia del lugar donde se use, por lo que los siguientes puntos
serán totalmente teóricos.

2. Formato.

Para comenzar a explicar su formato primero recordar que una expresión CRON no es otra cosa que una cadena de texto compuesta por 6 o 7 campos
separados por espacios en blanco.

Los campos tienen un orden concreto a la hora de indicar a que nos estamos refiriendo.

«Segundos» «Minutos» «Horas» «Día del mes» «Mes» «Día de la semana» «Año»

Los campos pueden contener alguno de los valores permitidos que se indicarán en la siguiente tabla.

Los campos pueden contener valores permitidos sobre los que se aplican diferentes combinaciones de carecteres especiales con el objetivo
de dotarles de nuevas características

Campo ¿Es obligatorio? Valores Permitidos Caracteres especiales
Segundos SI 0-59 , – * /
Minutos SI 0-59 , – * /
Horas SI 0-23 , – * /
Día del mes SI 1-31 , – * ? / L W
Mes SI 1-12 o JAN-DEC , – * /
Día de la semana SI 1-7 o SUN-SAT , – * ? / L #
Año NO Vacio | 1970-2099 , – * /

Importante : Recordar que las semanas comienzan en Domingo (valor 1)

3. Caracteres especiales.

En este punto se explicarán los caracteres especiales que de utilizarán con los diferentes campos sobre los que
se permite su aplicación.

  • * : Selecciona todos los valores de un campo (por ejemplo cada hora, cada minuto)
  • ? : Selecciona sin un valor específico cuando se puede utilizar (es similar a decir cualquiera)
  • – : Selecciona rango de valores (por ejemplo 4-6 que es de 4 a 6)
  • , : Selecciona valores específicos (por ejemplo MON,WED,FRI es decir los lunes, miárcoles y viernes )
  • / : Selecciona incrementos a partir del primer valor (por ejemplo 0/15 que es cada 15 minutos comenzando desde el minuto 0 -> 15, 30 ,45)
  • L (Día del mes) : Selecciona el último día del mes
  • L (Día de la semana) : Selecciona el último día de la semana (7 / sabado / SAT)
  • XL (Día de la semana) : Seleccona el último día de ese tipo del mes (por ejemplo 6L -> el último viernes del mes)
  • W : Selecciona el día de la semana (de lunes a viernes) más cercano al día (weekday)
  • LW : Selecciona el último weekday del mes
  • # : Selecciona la posición de un día del mes (por ejemplo 6#3 -> el tercer viernes del mes)

4. Ejemplos.

En este punto se detallarán algunos ejemplos de expresiones CRON

Expresión CRON Descripción
15 * * * * ? Se ejecuta cada 15 segundos
15 0 0 * * ? Se ejecuta a las 00:00:15
0 15 * * * ? Se ejecuta cada 15 minutos
0 0 15 * * ? Se ejecuta cada día a las 15:00:00
0 15 15 ? * * Se ejecuta cada día a las 15:15:00
0 15 15 * * ? Se ejecuta cada día a las 15:15:00
0 15 15 * * ? * Se ejecuta cada día a las 15:15:00
0 15 15 * * ? 2010 Se ejecuta cada día a las 15:15:00 durante el 2010
0 0/15 15 * * ? Se ejecuta cada 15 minutos a partir de las 15:00:00
0 10/15 15 * * ? Se ejecuta cada 15 minutos a partir de las 15:10:00
0 0/15 15,17 * * ? Se ejecuta cada 15 minutos a partir de las 15:00:00 hasta las 17:45:00
0 0-15 15 * * ? Se ejecuta cada 15 minutos empezando a las 15:00:00 y terminando a las 15:15:00
0 15,25 15 * * ? Se ejecuta a las 15:15:00 y a las 15:25:00
0 15 15 2 * ? Se ejecuta a las 15:15:00 del día 2 de cada mes
0 15 15 2 4 ? Se ejecuta a las 15:15:00 del día 2 del mes de abril
0 15 15 ? 4 FRI Se ejecuta a las 15:15:00 de cada viernes del mes de abril
0 15 15 ? * MON-FRI Se ejecuta a las 15:15:00 de lunes a viernes
0 15 15 L * ? Se ejecuta a las 15:15:00 del último día de cada mes
0 15 15 ? * 6L Se ejecuta a las 15:15:00 del último viernes del mes
0 15 15 ? * 6L 2010 Se ejecuta a las 15:15:00 del último viernes del mes durante el 2010
0 15 15 ? * 6L 2008-2010 Se ejecuta a las 15:15:00 del último viernes del mes entre el 2008 y el 2010
0 15 15 ? * 6#2 Se ejecuta a las 15:15:00 el segundo viernes de cada mes
0 15 15 1/5 * ? Se ejecuta a las 15:15:00 cada 5 dias a partir del primer dia del mes

5. Conclusiones.

Espero haberos podido ayudar a tener un poco más claro lo que son estas expresiones, para que sirven y sobre todo como implementarlas de forma correcta.

Para cualquier duda ya sabes que me podéis enviar un correo

Un saludo.

Víctor

mailto:vjmadrid@autentia.com

15 Comentarios

  1. Hola.

    Buen tutorial, pero te saco un error. El 4º ejemplo es erróneo.

    0 15 * * * ? Se ejecuta cada 15 minutos

    Eso no se ejecuta cada 15 minutos sino cada minuto 15:00 de cada hora.

    Lo correcto (para Se ejecuta cada 15 minutos) :

    0 0/15 * * * ? (Se ejecuta los minutos 0,15,30 y 45 de cada hora.)

    Corrígeme si me equivoco pero creo que es así.

  2. Muchas gracias por compartir Víctor, pero ¿Y si lo que deseo es ejecutar algo EXCEPTO el último día de mes?

    He probado esto, en dos sistemas Red Hat Enterprise Linux Server release 6.3 (Santiago) y en uno funciona y en otro no:

    50 23 * * * [[ $(date +\\\’%d\\\’) -ne $(cal | awk \\\’!/^$/{ print $NF }\\\’ | tail -1) ]] && /ruta_absoluta/blabla.sh

    Incluso en el sistema que falla, si ejecuto a mano:

    [[ $(date +\\\’%d\\\’) -ne $(cal | awk \\\’!/^$/{ print $NF }\\\’ | tail -1) ]] && /ruta_absoluta/blabla.sh

    funciona perfectamente pero si lo planifico con crontab me dice que

    From: root@waspro1.localdomain (Cron Daemon)
    To: was@waspro1.localdomain
    Subject: Cron [[ $(date +\\\’
    Content-Type: text/plain; charset=UTF-8
    Auto-Submitted: auto-generated
    X-Cron-Env:
    X-Cron-Env:
    X-Cron-Env:
    X-Cron-Env:
    X-Cron-Env:
    Message-Id:
    Date: Fri, 25 Apr 2014 12:50:01 +0200 (CEST)

    /bin/sh: -c: line 0: unexpected EOF while looking for matching \\\'\\\'
    /bin/sh: -c: line 1: unexpected token
    ▒\\\’ in conditional command
    /bin/sh: -c: line 1: syntax error: unexpected end of file

    De locos, vamos. Algo debo estar haciendo mal pero llevo toda la mañana y no soy capaz de descubrirlo.

    • Podrías hacer algo como 50 23 * * * 1-29 si te sirve, claro que no es totalmente eficiente ya que algunos meses tienen 31 días. pero a mi me funciona cuando no puedo ejecutar la tarea en los cierres de nomina de mi empresa.

  3. Hola Victor espero y me puedas ayudar.
    Lo que intento hacer es que en de 6 dìas se borre mi tabla que la tengo en SQL y me cree otra con los mismos campo, pero como hago para que eso se ejecute automaticamente,
    eclipse
    sql
    te agradeceria mucho si me puedes ayudar
    Nota : estaba usando un Truncate pero no me deja ya que tengo una llave foranea.

  4. Quisiera saber si podrías ayudarme con algunas dudas ya que no logrado solucionar….

    lo primero es lo que aparece en el siguiente foro http://stackoverflow.com/questions/34547113/quartz-how-can-i-use-injection

    lo segundo es poder saber como hago para ver el estado de un job,cron,proceso o como quieras llamarlo, ya que yo ejecuto la programación y este llama a 2 procesos almacenados en la base de datos… se ejecuta el primer proceso y al terminar ejecuta el segundo todo bajo el mismo job…. pero si el proceso esta croneado para que se ejecute cada 5 minutos por ejemplo pero no ha terminado la ejecutante de estos dos proceso, no quiero se vuelva a ejecutar, porque necesito que termine antes de empezar nuevamente…. no se si entiendes….

    Agradecería mucho que me pudieses ayudar…. Desde ya muchas gracias

    Erik Parra

  5. Solo hay una pequeña falla también en el primero de los ejemplos.

    Para que se ejecute cada 15 segundos, la manera correcta debe:

    0/15 * * * * ?

    Saludos.

  6. Hola Victor, muy buena entrada.

    Tengo una duda y si quiero que se ejecute cada minuto «0 0/1 * * * ?» pero que solo se ejecute siempre y cuando no este ya en ejecución?

    Muchas gracias, un saludo

  7. Una consulta, que pasa si programo para que se ejecute todos los 31 de todos los meses. Como haría para los meses que tienen 30 días y/o en el caso de febrero que solo tiene 28 o 29 días. Este se ejecuta el último día del meses o solo lo obvia?

  8. Tengo un pequeño problema, quiero que algo se ejecute cada X minutos, a partir de una hora específica. por ejemplo: cada 20min a partir de las 12:50.

    Entendería que la forma de expresar sería así:0 50/20 * ? * * *
    El problema está en que se calendariza de ésta manera:

    1. Tuesday, August 8, 2017 12:50 PM
    2. Tuesday, August 8, 2017 1:50 PM

    No se como hacer para que en lugar e que se ejecue a la 1:50, se ejecute a la 1:10 como debería…

  9. Hola!

    muchas gracias por el aporte, quisera preguntar que pasa si el usuario quiere guardar una tarea programada para todos los dias 30 del mes, pero llega febrero que solo tiene 28 dias y no se ejecuta, quisiera saber si puedo hacer esa excepcion (que si es febrero se ejecute el 28 y no el 30) dentro de la exprecion cron, o tengo que añadirle esa logica a mi codigo en java.

    Si puedo hacerlo dentro de la exprecion CRON como se podria hacer?

Dejar respuesta

Please enter your comment!
Please enter your name here