Cron es el programador de trabajos más antiguo y ampliamente desplegado en computación — el cron original de Unix salió en 1975 y su sintaxis de expresión ha sido heredada esencialmente sin cambios por todos los sistemas de programación modernos, desde los crontabs de Unix hasta los CronJobs de Kubernetes y los programadores en la nube de AWS, GCP y Azure. A pesar de esa ubicuidad, las expresiones cron son célebremente propensas a errores cuando se escriben a mano, y un solo carácter equivocado puede convertir un trabajo diario en uno cada hora que tumbe un sistema en producción. Las secciones a continuación explican la estructura de 5 campos, los caracteres especiales que la extienden y los detalles prácticos que atrapan incluso a ingenieros con experiencia.

La Estructura de 5 Campos y Qué Significa Cada Uno

Una expresión cron estándar tiene exactamente 5 campos separados por espacios en un orden fijo: minuto, hora, día del mes, mes, día de la semana. Cada campo acepta un número dentro de su rango válido (minuto 0–59, hora 0–23, día del mes 1–31, mes 1–12, día de la semana 0–6 con 0 = domingo), un comodín `*` que significa cualquier valor, o cualquiera de las sintaxis especiales descritas en la siguiente sección. Los campos siguen un patrón de acercamiento cronológico: el minuto es el más preciso, el día de la semana es el más general para patrones semanales. Un detalle complicado es el campo de día de la semana: históricamente distintas variantes de Unix no se ponían de acuerdo en si el domingo era 0 o 7, y el estándar moderno acepta ambos por compatibilidad. Los campos de mes y de día de la semana también aceptan abreviaturas de tres letras (`JAN`-`DEC`, `SUN`-`SAT`), que no distinguen mayúsculas y a menudo son más legibles que los valores numéricos. Cuando se especifican tanto el día del mes como el día de la semana, la mayoría de las implementaciones de cron usan lógica OR (el trabajo se ejecuta cuando cualquiera coincide), no lógica AND (que requiere que ambos coincidan). Esta es una de las fuentes de confusión más comunes — `0 0 15 * FRI` se ejecuta a la medianoche del día 15 de cada mes Y cada viernes, no solo los viernes que caen en día 15.

Caracteres Especiales: Paso, Rango, Lista y Comodines

Cuatro caracteres especiales extienden la sintaxis básica de cron y cubren la mayoría de las necesidades reales de programación. El asterisco `*` es el comodín de cada-valor: `* * * * *` se dispara cada minuto de cada hora de cada día. La barra `/` introduce valores de paso: `*/15` en el campo de minuto se dispara en el minuto 0, 15, 30, 45 — cada 15 minutos. Los pasos pueden combinarse con rangos: `9-17/2` se dispara en las horas 9, 11, 13, 15, 17. El guion `-` introduce rangos: `9-17` cubre de 9 AM a 5 PM inclusive en el campo de hora. La coma `,` introduce listas: `1,3,5` en el campo de día de la semana significa lunes, miércoles, viernes. Estos se combinan libremente — `0 9,12,17 * * 1-5` se dispara a las 9 AM, al mediodía y a las 5 PM en días entre semana. Algunas implementaciones de cron agregan especiales adicionales más allá de estos básicos. Quartz (usado por muchas bibliotecas de programación de Java) agrega `L` (último día del mes/semana), `W` (día hábil más cercano) y `#` (n-ésima ocurrencia de un día en un mes). Jenkins agrega `H` para valores hasheados que distribuyen programaciones idénticas a lo largo del tiempo para evitar efectos de estampida. Esta herramienta apunta al formato estándar de 5 campos usado por el crontab de Unix, AWS EventBridge, GCP Cloud Scheduler, Azure Logic Apps y la mayoría de las bibliotecas de programación populares como node-cron y python-crontab.

Detalles Prácticos que Atrapan Incluso a Ingenieros con Experiencia

Varios detalles de cron causan incidentes en producción de forma repetida incluso para equipos que usan cron todos los días. Primero, el manejo de zonas horarias: las expresiones cron se ejecutan en la zona horaria local del sistema por defecto, lo que significa que las transiciones de horario de verano en marzo y noviembre pueden hacer que los trabajos salten un día o se ejecuten dos veces según la dirección de la transición. Siempre configura los trabajos cron para ejecutarse en UTC donde sea posible, o prueba explícitamente los fines de semana de transición de horario de verano antes de desplegar programaciones sensibles al tiempo. Segundo, la lógica OR de día del mes vs día de la semana discutida arriba atrapa a ingenieros que esperan lógica AND. Si quieres que un trabajo se ejecute solo los viernes que caen en día 15, no puedes expresar eso en cron estándar — necesitas usar lógica AND en el código de la aplicación después de que se dispare el trabajo. Tercero, los casos límite de año bisiesto: `0 0 29 2 *` se ejecuta solo el 29 de febrero, lo que sucede una vez cada 4 años. Es fácil probarlo una vez y parecer que no funciona. Cuarto, `@reboot` y otros especiales como `@daily` o `@hourly` son soportados por muchas implementaciones pero no son portables — los programadores en la nube generalmente no los aceptan. Usa siempre la forma explícita de 5 campos para mayor portabilidad. Quinto, los trabajos de larga duración pueden traslaparse consigo mismos: si un trabajo se ejecuta cada 5 minutos pero tarda 7 minutos en ejecutarse, dos instancias correrán de forma concurrente. Envuélvelo con un archivo de bloqueo (`flock` en Linux) o usa coordinación a nivel de aplicación para prevenir esto.