Explicador de expresiones Cron

Pega una expresión cron y entiende exactamente lo que hace.

Ejemplos habituales

Cómo leer las expresiones cron

Una expresión cron estándar tiene 5 campos separados por espacios:

minuto hora día mes día-semana

* · cualquier valor   */n · cada n unidades   1,5 · en los valores 1 y 5   1-5 · rango de 1 a 5

Rangos: minuto (0-59), hora (0-23), día (1-31), mes (1-12), día de la semana (0-6, 0 = domingo)

Cómo funciona

  1. Introduce una expresión cron: pega una cadena cron de 5 o 6 campos como 0 9 * * 1-5.
  2. Lee la explicación en lenguaje claro: la herramienta muestra inmediatamente una descripción legible de cuándo se ejecuta la tarea.
  3. Visualiza las próximas ejecuciones: se muestra una lista de las 5 a 10 próximas ejecuciones programadas a partir de la fecha y hora actuales.
  4. Valida: las expresiones inválidas se resaltan con mensajes de error precisos que explican el problema.

Medio siglo de tics de un minuto

cron es el planificador más antiguo que aún se usa de forma continua y diaria en la mayoría de los servidores del mundo. Su primera aparición en el registro histórico es mayo de 1975, cuando una versión temprana se distribuyó desde AT&T Bell Laboratories como parte de la rama Research Unix. El nombre es un guiño a Cronos, la personificación griega del tiempo, y el diseño ha envejecido con extraña gracia: los mismos cinco campos separados por espacios que los ingenieros de Bell Labs tecleaban en /usr/lib/crontab a mediados de los 70 todavía mueven los CronJobs de Kubernetes, los schedules de GitHub Actions y la copia nocturna de la base de datos en un servidor privado virtual en algún lugar de Frankfurt en este preciso instante. La implementación de 1975 era mínima: había un único crontab, propiedad de root, que atendía a toda la máquina. Si un usuario quería una tarea recurrente, le pedía al administrador que añadiese una línea a mano. cron viajó al mundo más amplio en Version 7 Unix, lanzado en 1979. Robert Brown y Keith Williamson en la Purdue University extendieron cron para manejar varios usuarios a finales de 1979, introduciendo el flujo crontab -e por usuario. La reescritura decisiva llegó cuando Paul Vixie publicó vixie-cron 1.0 el 6 de mayo de 1987; vixie-cron formalizó los caracteres especiales e introdujo los atajos @reboot, @hourly, @daily, @weekly, @monthly, @yearly. Vixie 3.0 (27 de diciembre de 1993) añadió los valores de paso (/) y se incorporó, con parches menores, a casi todas las distribuciones Linux y BSD de la época. POSIX se puso al día en 1992 (IEEE Std 1003.2-1992). Cada peculiaridad del cron moderno -la numeración desfasada del domingo, el bug de unión-vs-intersección de los campos de día- es una cicatriz de esta evolución; nada se diseñó de una sola vez.

Anatomía de una expresión de cinco campos

Una expresión cron estándar son cinco campos separados por espacios. Leídos de izquierda a derecha preguntan: ¿qué minuto, de qué hora, de qué día-del-mes, de qué mes, de qué día-de-la-semana? Los rangos exactos no son negociables en cron POSIX: minuto 0-59, hora 0-23, día-del-mes 1-31, mes 1-12, día-de-la-semana 0-7 con 0 y 7 representando ambos al domingo. Cada campo acepta cinco operadores que se combinan libremente: * significa cualquier valor válido; , separa una lista de valores discretos (0,15,30,45 * * * * se ejecuta en punto, y cuarto, y media, y menos cuarto cada hora); - es un rango inclusivo (9-17 en el campo hora significa 9, 10, 11, 12, 13, 14, 15, 16, 17); / es un valor de paso (*/15 en el campo minuto significa cada quince minutos a partir de cero, es decir, 0, 15, 30, 45). Los meses y días de la semana también pueden escribirse con abreviaturas de tres letras: JAN-DEC y SUN-SAT. Un ejemplo práctico: */15 9-17 * * 1-5 se decodifica como cada quince minutos durante las horas 9 a 17 inclusive, todos los días del mes, cada mes del año, de lunes a viernes: «cada cuarto de hora durante el horario de oficina los días laborables».

La trampa día-del-mes / día-de-la-semana

La peculiaridad de cron con mayores consecuencias -la que ha causado caídas, copias de seguridad perdidas y ciclos de facturación silenciosamente erróneos en producción durante treinta y cinco años- es cómo cron combina los campos día-del-mes y día-de-la-semana cuando ambos están restringidos. La redacción POSIX es inusualmente precisa aquí: «si tanto “día del mes” (campo 3) como “día de la semana” (campo 5) están restringidos (no contienen “*”), entonces uno o ambos deben coincidir con el día actual». En otras palabras, cuando ninguno de los campos está como comodín, cron toma la unión de ambos: la tarea se ejecuta en cualquier día que coincida con cualquiera de las restricciones. Esto es lo opuesto a lo que la mayoría de los usuarios supone. Leer 0 0 13 * 5 en voz alta -«medianoche del 13, los viernes»- suena naturalmente como una intersección: solo el viernes 13. En vixie-cron y sus descendientes en realidad significa «cada 13 del mes y cada viernes», disparándose unas nueve veces al mes. Peor aún, vixie-cron decide si usar unión o intersección inspeccionando solo el primer carácter de cada campo de día. El propio Paul Vixie reconoció el comportamiento como un bug pero se negó a cambiarlo, señalando que arreglarlo violaría el principio de la menor sorpresa: ya había millones de crontabs escritas asumiendo que el comportamiento existente era deliberado. El bug es por tanto ahora una característica, inmortal y propagándose. El modelo mental pragmático: si te encuentras restringiendo a la vez día-del-mes y día-de-la-semana y realmente quieres intersección (por ejemplo, «el segundo martes de cada mes»), usa el operador # en implementaciones que lo soporten (Quartz, cronie con extensiones): 0 12 ? * 2#2. En cron POSIX puro la intersección es realmente imposible de expresar en una sola expresión y debes filtrar dentro del script que invoca la tarea cron.

Las macros de atajo

Estos atajos no son POSIX. Los entornos estrictos solo-POSIX rechazarán @daily; en la práctica cualquier implementación de cron con la que es probable encontrarse (vixie-cron, cronie, fcron, ISC cron, imágenes de contenedor) los soporta.

Los dialectos: estándar vs Quartz vs AWS vs K8s vs systemd

La «expresión cron» es ahora una pequeña familia de dialectos mutuamente incompatibles. cron 5 campos estándar (POSIX, vixie-cron, cronie): minuto hora día-del-mes mes día-de-la-semana -el mínimo común denominador universal. Quartz Scheduler (6 o 7 campos, ecosistema Java): segundos minutos horas día-del-mes mes día-de-la-semana [año]; introduce ?, L (último), W (día laborable), # (n-ésimo día de la semana del mes). El @Scheduled de Spring y Spring Boot usan Quartz. Kubernetes CronJob usa el cron 5 campos estándar, con un campo spec.timeZone aparte que pasó a GA en K8s 1.27 (el recurso CronJob en sí pasó a GA en 1.21, abril de 2021); el formato de zona horaria es la base IANA tz (Europe/Berlin, America/New_York). Los schedules cron de GitHub Actions usan cron POSIX 5 campos y se ejecutan en UTC. El cron de AWS EventBridge usa 6 campos (minutos horas día-del-mes mes día-de-la-semana año), exige el operador ? en día-del-mes o día-de-la-semana (no se pueden restringir ambos), y usa 1-7 con SUN=1, lo que significa que una expresión EventBridge 0 12 ? * 2 * se ejecuta a mediodía el lunes, no el martes. Los timers de systemd usan una sintaxis totalmente distinta (OnCalendar=*-*-* 02:00:00) y están reemplazando gradualmente a cron en Linux moderno para la planificación de sistema, aunque ambos se distribuyen en paralelo en cualquier distro mayor. Cloud Scheduler (Google Cloud) usa cron 5 campos estándar con configuración explícita de zona horaria. Traducir expresiones entre plataformas exige atención cuidadosa: un schedule de EventBridge copiado y pegado se ejecutará el día equivocado en vixie-cron por el desplazamiento de numeración de días.

Patrones comunes que merece la pena memorizar

Trampas comunes

Zona horaria. cron usa por defecto la hora local del sistema -sorprendente en máquinas cloud que vienen por defecto en UTC. Una tarea cron a las 9 AM en un servidor UTC se dispara a las 4 AM hora del Este. Los planificadores modernos (Kubernetes 1.27+, AWS EventBridge, Cloud Scheduler) añadieron campos de zona horaria explícitos; el cron clásico no. La regla «*/N empieza en 0». */15 es 0, 15, 30, 45, no 5, 20, 35, 50. Para empezar en un offset distinto de cero hay que enumerar (5,20,35,50) o usar la sintaxis Quartz-only 5/15. La trampa de la acumulación de 60 minutos. Una tarea que dura más que su intervalo de planificación puede acumularse: tres copias de seguridad de 30 minutos disparándose cada 15 minutos se solaparán. La mitigación estándar es flock(1): * * * * * /usr/bin/flock -n /tmp/myjob.lock /path/to/myjob garantiza que solo se ejecute una instancia a la vez; el flag -n hace que la adquisición del lock sea no bloqueante, así las invocaciones sucesivas terminan silenciosamente en lugar de hacer cola. Anomalías de horario de verano. Una tarea cron prevista para las 02:30 se disparará dos veces el día que se atrasan los relojes y nada el día que se adelantan. cron no tiene la noción de «hora de pared con horario de verano»; si tu planificación debe saltar las transiciones DST, ánclalo a una hora no afectada (3 AM o más tarde en la mayoría de zonas horarias) o usa un planificador que entienda las semánticas de zona horaria. Recorte del PATH. Las tareas cron se ejecutan con un PATH mínimo (/usr/bin:/bin) y un entorno casi vacío; los scripts que funcionan en tu shell interactivo pueden fallar en cron porque node, python3 o aws no están en el PATH heredado. Define PATH= al principio del crontab o usa rutas absolutas en el comando cron. Saturación de correo. Por defecto cron envía la salida de cada tarea al buzón local del usuario; en un servidor sin correo configurado esto llena silenciosamente /var/spool/mail hasta que se queda sin disco. O rediriges la salida (>/dev/null 2>&1), o pones MAILTO="" al principio del crontab, o configuras realmente un reenviador de correo.

Alternativas modernas: cuándo recurrir a otra cosa

cron es excelente para tareas recurrentes simples en una sola máquina. Es flojo en: planificación distribuida (la misma tarea disparada una sola vez a través de una flota en lugar de una vez por máquina), disparadores guiados por eventos (ejecutarse cuando una cola recibe un mensaje, no por reloj), monitorización (cron falla silenciosamente si la tarea sale con código distinto de cero salvo que configures el reenvío de correo), reintentos (sin mecanismo incorporado: las tareas fallidas vuelven a ejecutarse en el siguiente ciclo y acumulan estado) y dependencias (ejecutar la tarea B solo después de que A haya terminado con éxito). Para esos casos la respuesta moderna es alguna de: Kubernetes CronJob (planificación consciente del clúster con políticas de reintento y paralelismo), AWS EventBridge + Lambda o Step Functions (orientado a eventos con observabilidad incorporada), Apache Airflow o Prefect (orquestación de flujos de trabajo basados en DAG con dependencias explícitas), Temporal (ejecución de workflows duraderos), healthchecks.io (un «interruptor de hombre muerto» que te avisa cuando una tarea cron no se ejecuta en su horario). Para tareas recurrentes en una sola máquina en 2026, el cron simple sigue siendo la respuesta correcta; para cualquier otra cosa, una de las alternativas vale la configuración extra.

Preguntas frecuentes

¿Qué significa * en una expresión cron?

Un asterisco (*) en un campo cron significa «cualquier valor válido»: cada minuto, cada hora, cada día, cada mes, cada día-de-la-semana. * * * * * se ejecuta cada minuto de cada día. El asterisco también es especial en los campos día-del-mes y día-de-la-semana por la trampa unión-vs-intersección: cuando alguno de los campos de día tiene un * al inicio, vixie-cron usa modo intersección; cuando ninguno lo tiene, usa modo unión y se ejecuta sobre la unión de ambas restricciones.

¿Cómo ejecuto una tarea cron cada 15 minutos?

Usa la notación de paso: */15 * * * * se ejecuta cada 15 minutos: en xx:00, xx:15, xx:30 y xx:45. Ten en cuenta que */N siempre empieza en 0; no puedes usar */15 para decir «cada 15 minutos empezando en el minuto 5», para eso escribirías 5,20,35,50 * * * *. El cron en dialecto Quartz soporta 5/15 como alternativa no estándar.

¿Cuál es la diferencia entre cron y at?

cron ejecuta tareas en una planificación repetitiva (cada minuto, diaria, semanal). El comando at programa una tarea de una sola vez para que se ejecute en un momento futuro concreto: at 14:30 tomorrow encola una tarea para ese único momento. Usa cron para tareas recurrentes y at para ejecuciones futuras puntuales. Ambos descienden de la misma estirpe Bell Labs / vixie-cron y acabaron integrándose en el mismo demonio en la mayoría de los sistemas.

¿Por qué mi tarea cron no coincide con lo que esperaba?

Las cinco causas más comunes, en orden aproximado de frecuencia: (1) Confusión día-del-mes vs día-de-la-semana (cron usa la unión de ambos cuando ambos están restringidos, no la intersección. (2) Zona horaria) cron usa por defecto la hora local del servidor, a menudo UTC en máquinas cloud. (3) Problemas de PATH, el PATH de tu shell interactivo no se hereda, así que comandos que funcionan en el prompt pueden fallar en cron. (4) La trampa de que */N siempre empieza en 0. (5) Salida no capturada en ningún sitio, las tareas fallidas desaparecen silenciosamente si no has configurado correo o redirigido la salida a un archivo de log. El panel «10 próximas ejecuciones programadas» de este explicador es la forma más barata de verificar lo que tu expresión significa realmente antes de desplegar.

¿Esto soporta formatos cron no estándar?

Maneja el cron POSIX/vixie-cron de 5 campos estándar, la variante Quartz/Spring de 6 campos con segundos y las cadenas especiales @hourly, @daily, @weekly, @monthly, @yearly y @reboot. No maneja las extensiones Quartz completas (L, W, #) ni la numeración de días en base 1 de AWS EventBridge, para esos, usa el validador de la propia plataforma antes de desplegar.

¿Se envía mi expresión cron a algún sitio?

No. El parseo y la explicación se ejecutan enteramente en tu navegador vía JavaScript. Las expresiones pegadas nunca cruzan la red, verifícalo en la pestaña Red de DevTools mientras pulsas Explicar. Seguro para expresiones cron en configuraciones de CI de producción, código de infraestructura y runbooks operacionales donde el propio schedule pueda ser sensible (p. ej. schedules nocturnos de exportación de base de datos que sugieren ventanas de indisponibilidad).

Herramientas relacionadas