FlowingDev

Expresiones cron, explicadas: el lenguaje de los planificadores para viajar en el tiempo

Aprende cómo las expresiones cron, el pequeño pero poderoso lenguaje de la programación de tareas, le dicen a las computadoras cuándo ejecutar tareas automatizadas, desde backups hasta newsletters.

Probar la herramienta: Analizador de expresiones cron

En una frase

Una expresión cron es una cadena de caracteres compacta que define un horario recurrente, diciéndole básicamente a una computadora cuándo debe ejecutar una tarea automatizada.

El problema que resuelve

Allá por la edad oscura digital (los años 70), si querías que una computadora hiciera algo automáticamente —digamos, limpiar archivos temporales a medianoche— tenías que ponerte creativo. Podías escribir un script aparatoso que corría en un bucle, verificaba la hora y luego se "dormía" por un rato. Era un lío, ineficiente y propenso a romperse.

Y entonces llegó cron, un daemon (un proceso en segundo plano) nacido en los pasillos de Bell Labs en los inicios de Unix. El nombre es un guiño a Cronos, la personificación griega del tiempo, lo cual es de lo más geek que te puedas imaginar. El trabajo de cron era simple pero revolucionario: leer una lista de comandos y las horas en que debían ejecutarse, y luego ejecutarlos. Era un sistema de "configúralo y olvídate" para la automatización de tareas.

Para decirle a cron cuándo ejecutar las cosas, necesitaba un lenguaje. No un lenguaje verboso y similar al inglés, sino algo que una computadora pudiera analizar al instante. Ese lenguaje es la expresión cron. Resuelve el problema fundamental de cómo describir cualquier horario recurrente imaginable —"todos los lunes a las 9 AM", "el 1 y 15 de cada mes", "cada 10 minutos"— de una manera estandarizada y predecible. Sin él, cada desarrollador estaría reinventando la rueda de la planificación de tareas, y tu servidor sería un desastre caótico de comandos sleep() hechos a medida.

Cómo funciona por dentro

Para los no iniciados, una expresión cron parece una cadena de texto sin sentido, algo como */15 9-17 * * 1-5. Pero no es magia; es un mini-lenguaje altamente estructurado. Una vez que aprendes la sintaxis, puedes leer y escribir horarios como un profesional.

Los cinco campos del apocalipsis (y compañía)

Una expresión cron estándar se compone de cinco campos, separados por espacios. Cada campo representa una unidad de tiempo. Piensa en ello como un conjunto de cinco diales que giras para alinear el momento correcto.

Campo Valores permitidos Caracteres especiales permitidos
Minuto 0-59 * , - /
Hora 0-23 * , - /
Día del Mes 1-31 * , - / ? L W
Mes 1-12 o JAN-DEC * , - /
Día de la Semana 0-7 o SUN-SAT * , - / ? L #

Algunas implementaciones modernas de cron añaden un sexto campo para el año (1970-2099) o incluso un campo inicial para los segundos (0-59), pero el formato clásico de cinco campos es el más común.

Una nota sobre el Día de la Semana: A menudo se aceptan tanto 0 como 7 para el domingo. Es una buena idea apegarse a una convención (como 0=Dom, 6=Sáb).

Caracteres especiales: el lenguaje secreto

El verdadero poder de las expresiones cron proviene de un puñado de caracteres especiales que modifican los números.

  • * (El "todos"): Este es el comodín. Un asterisco en el campo Hora significa "cada hora del día". Un asterisco en cada campo (* * * * *) significa "cada minuto de cada hora de cada día de cada mes...". Ya te haces una idea.

  • , (El "y"): La coma actúa como un separador de lista. 1,15 en el campo Día del Mes significa "el día 1 y el 15 del mes".

  • - (El "hasta"): El guion define un rango. 9-17 en el campo Hora significa "cada hora desde las 9 AM hasta las 5 PM".

  • / (El "paso"): La barra se usa para especificar incrementos. */10 en el campo Minuto significa "cada 10 minutos". También puedes combinarlo con un rango: 0-30/5 significa "cada 5 minutos dentro de los primeros 30 minutos de la hora" (es decir, a las :00, :05, :10, :15, :20, :25, :30).

  • ? (El "no me importa"): Este es complicado pero importante. No siempre puedes especificar tanto un Día del Mes como un Día de la Semana porque pueden entrar en conflicto. ¿Qué pasa si dices "ejecutar el día 13 del mes y en viernes", pero el día 13 cae en miércoles? El ? resuelve esto diciendo: "He especificado uno de estos campos, así que ignora el otro". Configurarías el horario como * * 13 * ? (ejecutar el día 13, no me importa qué día de la semana sea) o * * ? * 5 (ejecutar cada viernes, no me importa qué día del mes sea).

  • L (El "último"): L en el campo Día del Mes significa "el último día del mes" (o sea, 31 de enero, 28/29 de febrero, etc.). En el campo Día de la Semana, significa "el último X del mes". Por ejemplo, 5L significa "el último viernes del mes".

  • W (El "día de la semana"): 15W en el campo Día del Mes significa "el día de la semana más cercano al día 15 del mes". Si el 15 es un sábado, la tarea se ejecutará el viernes 14. Si el 15 es un domingo, se ejecutará el lunes 16.

  • # (El "enésimo"): Esto es para encontrar cosas como "el tercer viernes del mes". La expresión para eso sería * * ? * 5#3.

Juntando todo

Vamos a decodificar algunas expresiones comunes:

# Ejecutar cada noche a la medianoche
0 0 * * *
  • 0 en el campo de minuto: en el minuto cero (al inicio de la hora).
  • 0 en el campo de hora: en la hora cero (medianoche).
  • * * * en los otros campos: cada día de cada mes de cada semana.
# Ejecutar a las 8:30 AM todos los días laborables (Lun-Vie)
30 8 * * 1-5
  • 30 en el campo de minuto: a los 30 minutos de la hora.
  • 8 en el campo de hora: a las 8 AM.
  • * * para día del mes y mes: no importa.
  • 1-5 para día de la semana: de lunes a viernes.
# Ejecutar cada 15 minutos durante el horario laboral (9am-5pm) los días de semana
*/15 9-17 * * 1-5
  • */15: cada 15 minutos.
  • 9-17: para las horas 9, 10, 11, 12, 13, 14, 15, 16 y 17.
  • 1-5: de lunes a viernes.

Historias del mundo real

El caso del backup de medianoche

La base de datos de una startup estaba creciendo rápidamente. El sysadmin principal sabía que necesitaban backups diarios, pero ejecutar el script de backup durante el día ralentizaba toda la aplicación hasta casi detenerla. Los usuarios se quejaban y se perdían ventas potenciales. ¿La solución? Un simple cron job. Programó el script de backup, que consumía muchos recursos, para que se ejecutara a las 2 AM, cuando el tráfico del sitio era prácticamente nulo. La expresión 0 2 * * * se convirtió en el héroe silencioso de la empresa, asegurando que sus datos estuvieran a salvo sin interrumpir a un solo usuario. Lección: Programa tareas que consumen muchos recursos para las horas de menor actividad y así mantener el rendimiento.

El newsletter olvidado

Un pequeño sitio de e-commerce quería enviar un correo de "Ofertas Semanales" todos los martes por la mañana para impulsar las ventas. Durante meses, una persona de marketing llamada Dave tenía la tarea de hacer clic manualmente en "Enviar" a las 10 AM. Pero una semana, Dave se enfermó. El newsletter nunca se envió y las ventas de ese martes fueron pésimas. El desarrollador principal intervino y automatizó el proceso. Escribió un script para enviar el newsletter y lo conectó a un cron job: 0 10 * * 2. A partir de entonces, el newsletter se envió como un reloj, sin importar quién estuviera en la oficina. Lección: Automatiza tareas repetitivas y sensibles al tiempo para mejorar la fiabilidad y eliminar el error humano.

El caché obsoleto

Un sitio web de noticias se enorgullecía de dar las últimas horas, pero su página de inicio a menudo se sentía lenta. Su contenido estaba en caché para mejorar el rendimiento, pero el caché solo se limpiaba cuando un desarrollador lo hacía manualmente. Esto significaba que los nuevos artículos a veces tardaban horas en aparecer. Un desarrollador configuró un cron job para limpiar y reconstruir automáticamente el caché del sitio cada cinco minutos. Con la expresión */5 * * * *, el sitio se volvió drásticamente más rápido y más actualizado, ya que se garantizaba que el nuevo contenido estaría visible en cuestión de minutos. Lección: Usa cron para tareas periódicas de "mantenimiento" como la invalidación de caché para mantener los sistemas frescos y con buen rendimiento.

Errores y trampas comunes

  • Problemas con la zona horaria: Un clásico problema de "se ejecuta a la hora incorrecta". Los cron jobs casi siempre se ejecutan usando la hora del sistema del servidor, que podría ser UTC o alguna otra zona horaria en la que no te encuentras. Programar una tarea para las 9 AM de tu hora podría significar que se ejecute a las 2 PM hora del servidor. Siempre ten en cuenta la zona horaria de tu servidor.

  • El conflicto entre Día del Mes y Día de la Semana: Un error de novato común es poner un valor tanto en el campo de Día del Mes como en el de Día de la Semana (p. ej., * * 1 FRI). La mayoría de los daemons de cron interpretan esto con una condición OR: "ejecutar el 1º del mes O cualquier viernes". Esto rara vez es lo que quieres. Si quieres "el primer viernes del mes", necesitas usar * * ? * 5#1 o un script más complejo. Usa el carácter ? para evitar ambigüedades.

  • Olvidar la redirección de salida: Por defecto, todo lo que tu script imprime en la salida estándar o en el error estándar se envía por correo electrónico al usuario propietario del crontab. Esto suena útil, pero puede llenar rápidamente un buzón de correo con notificaciones inútiles. La mejor práctica es manejar explícitamente la salida: envíala a un archivo de registro (>> /var/log/myjob.log 2>&1) o descártala si no te importa (> /dev/null 2>&1).

  • La tarea que se solapa: Configurar una tarea como * * * * * significa "iniciar una nueva instancia de esta tarea al comienzo de cada minuto". Si tu tarea tarda 90 segundos en ejecutarse, tendrás ejecuciones superpuestas, lo que puede llevar a condiciones de carrera, agotamiento de recursos y todo tipo de caos.

  • El entorno minimalista: Tu shell interactiva está llena de variables de entorno útiles como $PATH. Un cron job se ejecuta en un entorno árido y despojado. Tu script que funciona perfectamente desde la línea de comandos podría fallar en cron porque no puede encontrar programas como node o python. La solución es usar rutas absolutas para todos los comandos (p. ej., /usr/bin/node en lugar de node) o establecer la variable PATH al principio de tu archivo crontab.

Por qué debe estar en tu radar

Podrías pensar que cron es solo para administradores de sistemas de la vieja escuela, pero su ADN está en todas partes.

  • Backend & DevOps: Es el estándar de facto para programar trabajos en segundo plano, desde el mantenimiento de bases de datos y la rotación de logs hasta el despliegue de código.
  • Desarrollo Web: ¿Necesitas enviar informes diarios por correo electrónico, limpiar un caché o generar un sitemap? Cron es tu herramienta.
  • Plataformas en la Nube: Servicios como AWS Lambda Scheduled Events y Google Cloud Scheduler usan expresiones cron para definir sus disparadores. La sintaxis es un lenguaje universal para la programación de tareas, incluso en los entornos más modernos y "serverless".

Aprender a leer y escribir expresiones cron es una habilidad fundamental. Es la clave que desbloquea la automatización, permitiéndote construir sistemas más robustos, fiables y autosuficientes. Es una de esas pequeñas cosas que, una vez que la aprendes, verás oportunidades para usarla en todas partes.

Profundiza más

Teoría lista. Hora de ensuciarse las manos — 100% en tu navegador.

Probar la herramienta: Analizador de expresiones cron