DevTools

Cheatsheet Cron Jobs

Agendamento de tarefas em sistemas Unix/Linux

Volver a los lenguajes
Cron Jobs
23 tarjetas encontradas
Categorías:
Versiones:

Sintaxe e Campos


5 cards
Estructura base
# ┌──────── minuto (0-59)
# │ ┌────── hora (0-23)
# │ │ ┌──── día del mes (1-31)
# │ │ │ ┌── mes (1-12)
# │ │ │ │ ┌─ día de la semana (0-7)
# │ │ │ │ │
# * * * * * comando-a-ejecutar

# 0 y 7 = domingo

Cada * representa un campo temporal. Los 5 campos definen CUÁNDO ejecutar. El resto es el comando. El orden es fijo: minuto, hora, día, mes, semana. 0 y 7 ambos significan domingo.

Campo día de la semana
# Día de la semana (0-7, 0 y 7 = domingo)
0 9 * * 1      # lunes a las 09:00
0 9 * * 1-5    # lun a vie a las 09:00
0 0 * * 0      # domingo a medianoche
0 9 * * MON    # = 1 (nombres: SUN-SAT)
0 9 * * 6,0    # sábado y domingo

# NOTA: si día-mes Y día-semana están
# restringidos, ejecuta en CUALQUIERA (OR)

El quinto campo es el día de la semana (0-7). Acepta nombres: SUN, MON, TUE... Si tanto día-mes como día-semana están restringidos (no *), cron ejecuta cuando CUALQUIERA coincida (lógica OR, no AND).

Campo minuto
# Minuto (0-59)
0 * * * *    # al inicio de cada hora
30 * * * *   # cada media hora
*/5 * * * *  # cada 5 minutos
15,45 * * * * # en los minutos 15 y 45
0-30 * * * * # minutos 0 a 30 (cada min)

El primer campo controla el minuto (0-59). 0 ejecuta al inicio de la hora. */5 ejecuta cada 5 minutos. Es el campo más usado para tareas frecuentes. Valores válidos: 0 a 59.

Campo hora
# Hora (0-23, formato 24h)
0 3 * * *      # a las 03:00
0 15 * * *     # a las 15:00
0 9,12,18 * * * # a las 09h, 12h y 18h
0 9-17 * * *   # cada hora, 09h a 17h
0 */6 * * *    # cada 6 horas (0h,6h,12h,18h)

El segundo campo define la hora (0-23). Formato 24h sin AM/PM. 9-17 cubre el horario laboral. */6 ejecuta cada 6 horas. Combine con minuto 0 para horas exactas.

Campos día y mes
# Día del mes (1-31)
0 0 1 * *      # día 1 de cada mes
0 0 15 * *     # día 15 de cada mes
0 0 1,15 * *   # días 1 y 15

# Mes (1-12 o JAN-DEC)
0 0 1 1 *      # 1 de Enero
0 0 1 6,12 *   # Junio y Diciembre
0 0 * 1-3 *    # Ene, Feb y Mar (diario)

El tercer campo es el día del mes (1-31). El cuarto es el mes (1-12 o nombres JAN-DEC). Si el día es *, ejecuta todos los días. Cuidado: el día 31 no existe en todos los meses.

Operadores e Valores


5 cards
Asterisco (todos)
* * * * *    # cada minuto (todos los valores)
0 * * * *    # minuto 0 de CADA hora
0 0 * * *    # medianoche de CADA día
0 0 1 * *    # día 1 de CADA mes

# * = "cualquier valor" para ese campo
# Equivale al rango completo:
# * en el minuto = 0-59
# * en la hora   = 0-23

El * significa "todos los valores posibles" para el campo. En el minuto equivale a 0-59, en la hora a 0-23. Es el valor por defecto. Úselo cuando no quiera restringir ese campo específico.

Atajos especiales
@reboot     # al iniciar el sistema
@yearly     # = 0 0 1 1 *   (1 Ene, 00:00)
@annually   # = @yearly
@monthly    # = 0 0 1 * *   (día 1, 00:00)
@weekly     # = 0 0 * * 0   (domingo, 00:00)
@daily      # = 0 0 * * *   (medianoche)
@midnight   # = @daily
@hourly     # = 0 * * * *   (inicio de la hora)

# Más legibles que la sintaxis numérica

Los atajos @daily, @hourly etc. sustituyen expresiones numéricas. @reboot ejecuta una vez al arrancar el sistema. Son más legibles y menos propensos a errores. No todos los sistemas soportan todos los atajos — verifique la documentación.

Coma (lista)
# Lista de valores separados por coma
0 9,12,15 * * *    # a las 09h, 12h y 15h
0 0 1,15 * *       # días 1 y 15
0 9 * * 1,3,5      # lun, mié y vie
0 0 * 1,4,7,10 *   # Ene, Abr, Jul, Oct

# Puede combinar con rangos:
0 9-12,14-17 * * * # 9h-12h y 14h-17h

La coma crea una lista de valores discretos. 9,12,15 ejecuta en esas 3 horas. Puede mezclar con rangos: 9-12,14-17. Sin espacios tras la coma. Ideal para múltiples horarios específicos.

Guion (rango)
# Rango continuo de valores
0 9-17 * * *     # cada hora, 09h a 17h
0 0 * * 1-5      # lunes a viernes
*/10 8-18 * * *  # cada 10min, 08h a 18h
0 0 1-15 * *     # primeros 15 días del mes

# El rango es inclusivo:
# 9-17 = 9,10,11,12,13,14,15,16,17

El guion define un rango continuo e inclusivo. 9-17 incluye 9, 10, 11... hasta 17. 1-5 en el día de la semana = lun a vie. Combine con / para pasos dentro del rango: 8-18/2 = horas pares.

Barra (paso)
# Paso: ejecuta cada N unidades
*/5 * * * *      # cada 5 minutos
*/15 * * * *     # cada 15 minutos
0 */2 * * *      # cada 2 horas
0 */6 * * *      # cada 6 horas
0 9-17/2 * * *   # 9h, 11h, 13h, 15h, 17h

# */N = "cada N" a partir del mínimo
# Equivale a: 0-N/max con paso N

La barra define el paso (frecuencia). */5 = cada 5 unidades. */15 en el minuto = 0, 15, 30, 45. Puede combinar con un rango: 9-17/2 = horas impares entre 9 y 17. Muy usado para tareas periódicas.

Exemplos Práticos


5 cards
Backups diarios
# Backup de la BD a las 02:30 todos los días
30 2 * * * /usr/bin/mysqldump -u root mi_bd > /backups/bd_$(date +\%F).sql

# Backup de ficheros a las 03:00
0 3 * * * tar -czf /backups/site_$(date +\%F).tar.gz /var/www

# Limpiar backups de más de 30 días
0 4 * * * find /backups -mtime +30 -delete

Los backups son el uso más común de cron. $(date +\%F) genera un nombre con la fecha (escape el % con \). Combine backup + limpieza automática. Programe en horario de bajo tráfico (madrugada).

Scripts con PHP y Node
# PHP con ruta absoluta
0 3 * * * /usr/bin/php /var/www/app/cron.php

# Laravel Artisan
* * * * * cd /app && php artisan schedule:run

# Node.js
*/10 * * * * /usr/bin/node /scripts/worker.js

# Python
0 */4 * * * /usr/bin/python3 /scripts/etl.py

# Use SIEMPRE rutas ABSOLUTAS

Use siempre la ruta absoluta del intérprete (/usr/bin/php). Cron no carga el PATH del usuario. Para Laravel, el estándar es schedule:run cada minuto. Use cd si el script depende del directorio de trabajo.

Tareas frecuentes
# Cada 5 minutos: verificar la cola
*/5 * * * * php /app/artisan queue:work --stop-when-empty

# Cada hora: limpiar la caché
0 * * * * php /app/artisan cache:clear

# Cada 15 minutos: sync de datos
*/15 * * * * /app/scripts/sync.sh

# Cada minuto: monitorización
* * * * * curl -s https://mi-site.com/health

Las tareas recurrentes usan */N para la frecuencia. */5 = 5 minutos, */15 = 15 minutos. Para Laravel, prefiera el schedule interno. curl para health checks simples. Evite tareas cada minuto si es posible.

Horario laboral
# Informes a las 09:00 de lun a vie
0 9 * * 1-5 /scripts/informe_diario.sh

# Recordatorio a las 17:30 de lun a vie
30 17 * * 1-5 /scripts/lembrete.sh

# Limpieza de sesión cada 30min (24/7)
*/30 * * * * php /app/artisan session:gc

# Verificación cada 2h en días laborables
0 9-18/2 * * 1-5 /scripts/check.sh

1-5 en el día de la semana restringe a lun-vie. Combine con 9-17 en la hora para el horario laboral. 9-18/2 ejecuta a las 9h, 11h, 13h, 15h, 17h. Las tareas de mantenimiento pueden correr 24/7 con * en el día.

Mensuales y anuales
# Facturación el día 1 a las 06:00
0 6 1 * * /scripts/facturacao.sh

# Informe trimestral (Ene,Abr,Jul,Oct)
0 8 1 1,4,7,10 * /scripts/trimestral.sh

# Renovación de certificados (día 15)
0 3 15 * * certbot renew --quiet

# Aniversario del sistema (1 Ene)
0 0 1 1 * /scripts/aniversario.sh

Las tareas mensuales fijan el día del mes: 0 6 1 * * = día 1 a las 6h. Trimestral usa una lista de meses: 1,4,7,10. certbot renew es un caso clásico mensual. Para "último día del mes", use lógica en el script.

Gestão e CLI


4 cards
Comandos crontab
crontab -e     # editar el crontab del usuario
crontab -l     # listar entradas actuales
crontab -r     # eliminar TODAS las entradas
crontab -u user -e  # editar el de otro user

# Editar con un editor específico:
EDITOR=nano crontab -e
EDITOR=vim crontab -e

crontab -e abre el editor para gestionar jobs. -l lista sin editar. -r borra todo (¡cuidado!). -u para otro usuario (requiere root). El editor lo define EDITOR o VISUAL.

Ficheros del sistema
/etc/crontab          # crontab del sistema
/etc/cron.d/          # jobs de paquetes
/var/spool/cron/      # crontabs de usuarios

# Directorios de ejecución automática:
/etc/cron.hourly/     # scripts cada hora
/etc/cron.daily/      # scripts diarios
/etc/cron.weekly/     # scripts semanales
/etc/cron.monthly/    # scripts mensuales

# Basta con colocar un script ejecutable ahí

/etc/crontab es el fichero global del sistema. /etc/cron.d/ para jobs de paquetes. Los directorios cron.daily/ etc. ejecutan scripts automáticamente — basta con copiar un fichero ejecutable. Más simple que editar crontab para tareas estándar.

Permisos y control
# Permitir usuarios:
/etc/cron.allow    # whitelist (solo estos)
/etc/cron.deny     # blacklist (todos excepto)

# Verificar el servicio:
systemctl status cron
systemctl restart cron
systemctl enable cron    # arranque automático

# Logs (Ubuntu/Debian):
grep CRON /var/log/syslog

cron.allow y cron.deny controlan quién puede usar cron. Si cron.allow existe, solo los listados pueden. El servicio se llama cron (Debian) o crond (RHEL). Logs en /var/log/syslog filtrando por CRON.

Redireccionar salida
# Guardar salida en un fichero:
0 3 * * * /script.sh >> /var/log/job.log 2>&1

# Descartar salida (silenciar):
0 3 * * * /script.sh > /dev/null 2>&1

# Guardar solo errores:
0 3 * * * /script.sh 2>> /var/log/errores.log

# Enviar por email (si MAILTO está definido):
MAILTO=admin@ejemplo.com
0 3 * * * /script.sh

Por defecto, cron envía la salida por email. >> /fichero 2>&1 guarda stdout y stderr. > /dev/null 2>&1 silencia todo. 2>> captura solo errores. MAILTO define el destinatario de los emails. Redireccione siempre para evitar emails no deseados.

Avançado e Boas Práticas


4 cards
Variables de entorno
# Definir al inicio del crontab:
SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin
MAILTO=admin@ejemplo.com
HOME=/home/deploy

# O inline en el comando:
0 3 * * * DB_PASS=secret /script.sh

# Cargar env desde un fichero:
0 3 * * * . /home/user/.env && /script.sh

Cron tiene un PATH mínimo — defínalo explícitamente. SHELL define el intérprete. MAILTO controla los emails. Use . /fichero.env para cargar variables. Sin esto, comandos como node o composer no se encuentran.

Evitar solapamiento
# flock: impide ejecución simultánea
*/5 * * * * flock -n /tmp/job.lock /script.sh

# Alternativa con PID file:
* * * * * [ ! -f /tmp/job.pid ] && /script.sh & echo $! > /tmp/job.pid

# systemd timer (alternativa moderna):
# /etc/systemd/system/job.timer
# [Timer]
# OnCalendar=*:0/5

flock -n crea un lock file — si ya está en ejecución, no ejecuta. Esencial para tareas que tardan más que el intervalo. Sin lock, varias instancias pueden corromper datos. systemd timers son la alternativa moderna con mejor control.

Depuración y logs
# Verificar si cron está activo:
systemctl status cron
pgrep cron

# Logs en tiempo real:
tail -f /var/log/syslog | grep CRON

# Probar la expresión antes de programar:
# Use: crontab.guru (online)

# Script de prueba con timestamp:
* * * * * echo "$(date): corrió" >> /tmp/cron_test.log

# Eliminar tras confirmar:
# crontab -e → borrar la línea de prueba

tail -f /var/log/syslog | grep CRON muestra las ejecuciones en tiempo real. crontab.guru explica las expresiones visualmente. Para depurar, programe * * * * * con echo y revise el log. Problemas comunes: PATH incorrecto y permisos.

Buenas prácticas
# 1. Rutas absolutas SIEMPRE
0 3 * * * /usr/bin/php /app/script.php

# 2. Redireccionar la salida
0 3 * * * /script.sh >> /var/log/job.log 2>&1

# 3. Usar flock para tareas largas
*/5 * * * * flock -n /tmp/j.lock /script.sh

# 4. Comentar cada entrada
# Backup diario de la base de datos
30 2 * * * /scripts/backup.sh

# 5. Probar el comando manualmente antes

Use siempre rutas absolutas — cron no hereda el PATH. Redireccione la salida a logs. Use flock para evitar solapamiento. Comente cada job para el mantenimiento futuro. Pruebe el comando manualmente antes de programar. Prefiera scripts a comandos inline anchos.