Guias

Cron y systemd timers en Linux: automatiza todo en 2026

Si alguna vez quisiste que algo se ejecutara automáticamente cada hora, día, o lunes a las 3 AM — cron y systemd timers son tus herramientas. Esta guía cubre los dos, con ejemplos del mundo real y los errores que casi todos cometen al empezar.

TL;DR — Lo que vas a tener al final

  • Tiempo de setup: 30 minutos a 2 horas dependiendo de la complejidad del entorno.
  • Requisitos: Acceso root, Linux moderno, conexión a internet para descargar dependencias.
  • Resultado: Servicio funcional y estable, documentado paso a paso.
  • Troubleshooting: Logs estándar en /var/log/, comandos de verificación al final de cada sección.

¿Qué es cron?

cron es un demonio (servicio) que ejecuta comandos en horarios programados. Viene en casi todas las distribuciones Linux desde los 90s. La configuración se llama crontab.

Cómo funciona:

1. El demonio cron se inicia al boot.

2. Cada minuto revisa si hay tareas para ejecutar AHORA.

3. Ejecuta los comandos como el usuario dueño del crontab.

4. Mandá el output a un log (o a un mail si tienes).

Sintaxis de crontab

Cada línea del crontab es una tarea con este formato:

MINUTO HORA DIA-DEL-MES MES DIA-DE-LA-SEMANA COMANDO
Campo Rango Ejemplo
MINUTO 0-59 0 (en punto)
HORA 0-23 3 (3 AM)
DIA-DEL-MES 1-31 * (todos)
MES 1-12 * (todos)
DIA-DE-LA-SEMANA 0-7 1 (lunes, 0 y 7 = domingo)

Ejemplos comunes

# Cada minuto
* * * * * /script.sh
# Cada 5 minutos
*/5 * * * * /script.sh
# Cada hora, en punto
0 * * * * /script.sh
# Cada día a las 3:30 AM
30 3 * * * /backup.sh
# Lunes a las 2 AM (mantenimiento)
0 2 * * 1 /cleanup.sh
# Primer día del mes
0 0 1 * * /reporte-mensual.sh
# Cada 15 minutos de lunes a viernes de 9 a 18
*/15 9-18 * * 1-5 /sync.sh
# Cada domingo a medianoche
0 0 * * 0 /weekly-backup.sh

Cómo editar tu crontab

crontab -e            # editar el crontab del usuario actual
crontab -l            # listar
crontab -r            # borrar (¡cuidado, no hay undo!)
crontab -u roger -e   # editar el de otro usuario (como root)

Consejo importante: la primera vez que hagas crontab -e, te pregunta qué editor usar. Elegí nano si no quieres sufrir. Cambialo después con select-editor.

Variables de entorno en cron

Cron corre con un environment mínimo. No carga tu ~/.bashrc ni ~/.profile, lo cual es fuente de muchos problemas.

Si tu script usa Python en /opt/custom/bin/python, el cron no lo va a encontrar porque no tiene el PATH completo.

Solución: definí el environment al inicio del crontab:

SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOME=/home/roger
MAILTO=""
# Ahora tus tareas
0 3 * * * /home/roger/backup.sh

O en el script:

#!/bin/bash
export PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
cd /home/roger
python3 /home/roger/sync.py

Errores comunes con cron

1. No poner la ruta completa al comando

# ❌ Mal
*/5 * * * * python3 script.py
# ✅ Bien
*/5 * * * * /usr/bin/python3 /home/roger/script.py

Para saber la ruta: which python3.

2. Olvidar que el environment es limitado

# Si tu script usa ~/.config/mi-app/config.yml, no va a encontrar
# el home directory. Especificá HOME= en el crontab.

3. El script necesita permisos especiales

Si el script toca /var/log/ o /etc/, necesita correr como root. usa el crontab de root:

sudo crontab -e

4. El script no es ejecutable

chmod +x /home/roger/backup.sh

O llamalo con bash:

0 3 * * * bash /home/roger/backup.sh

5. Olvidar el newline final

Sí, en serio. El crontab necesita terminar con newline. Si no, la última tarea no se ejecuta.

echo "" >> /tmp/crontab.tmp

6. Redireccionar output para debug

Por default cron manda el output a un mail local (si tienes) o a /dev/null. Para debug:

*/5 * * * * /script.sh >> /tmp/cron.log 2>&1

Después: tail -f /tmp/cron.log.

Alternativa moderna: systemd timers

cron tiene 30+ años y funciona, pero tiene limitaciones:

  • No se integra bien con systemd.
  • No tiene dependencias (no puedes decir “corré X después de Y terminó”).
  • No maneja reintentos elegantes.
  • Logging básico (vas a syslog).

systemd timers es la alternativa moderna. Es parte de systemd y resuelve estos issues. Para servidores con systemd, te recomiendo timer sobre cron.

Cómo crear un timer

necesitas dos archivos:

1. El servicio (/etc/systemd/system/mi-tarea.service):

[Unit]
Description=Mi backup automático
[Service]
Type=oneshot
ExecStart=/home/roger/backup.sh
User=roger
WorkingDirectory=/home/roger

2. El timer (/etc/systemd/system/mi-tarea.timer):

[Unit]
Description=Corre mi backup diario a las 3 AM
[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
[Install]
WantedBy=timers.target

Activar:

sudo systemctl daemon-reload
sudo systemctl enable mi-tarea.timer
sudo systemctl start mi-tarea.timer
systemctl list-timers --all

Sintaxis de OnCalendar

OnCalendar es más legible que cron. Ejemplos:

OnCalendar=hourly                  # cada hora
OnCalendar=daily                   # cada día a medianoche
OnCalendar=weekly                  # cada lunes a medianoche
OnCalendar=*-*-* 03:00:00          # diario a las 3 AM
OnCalendar=Mon..Fri 09:00:00       # lunes a viernes 9 AM
OnCalendar=*-01-01 00:00:00        # cada 1 de enero
OnCalendar=*:0/15                  # cada 15 minutos
OnCalendar=Mon *-*-* 00,12:00:00   # lunes cada 12 horas

Validar antes de activar:

systemd-analyze calendar "Mon *-*-* 00,12:00:00"

Ventajas de systemd timers sobre cron

Feature cron systemd timer
Integración con journald ❌ ✅
Dependencias ❌ ✅ (Requires=, After=)
Condiciones (CPU load, etc.) ❌ ✅ (ConditionCPUPressure=)
Reintentos ❌ ✅ (Restart=on-failure)
Estado persistente ❌ ✅ (sigue reglas aunque el server estuvo caído)
Logging estructurado ❌ ✅ (journalctl -u mi-tarea)

Persistent=true es lo más útil: si tu servidor estuvo apagado a las 3 AM cuando tenía que correr el backup, lo corre cuando arranca.

Cuándo usar cron vs timer

usa cron si:

  • trabajas en un sistema sin systemd (poco común hoy).
  • necesitas algo simple que solo corre y se olvida.
  • tienes un crontab legacy que quieres mantener.

usa timer si:

  • Es un servidor moderno (cualquier Debian 8+, Ubuntu 16+, Fedora, Arch).
  • quieres logging y debugging decentes.
  • necesitas dependencias o reintentos.
  • tienes timers que se ejecutan en horarios críticos donde no quieres perderlos.

Ejemplos del mundo real

Backup diario con restic

/etc/systemd/system/backup-restic.service:

[Unit]
Description=Backup diario con restic
After=network-online.target
[Service]
Type=oneshot
User=roger
Environment="RESTIC_REPOSITORY=sftp:roger@nas:/backup/soylinux"
Environment="RESTIC_PASSWORD_FILE=/home/roger/.restic-password"
ExecStart=/usr/bin/restic backup /home/roger
ExecStartPost=/usr/bin/restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6

/etc/systemd/system/backup-restic.timer:

[Unit]
Description=Backup diario a las 3 AM
[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
RandomizedDelaySec=300
[Install]
WantedBy=timers.target

Limpieza de logs vieja

/etc/systemd/system/logrotate-cleanup.service:

[Unit]
Description=Limpiar logs comprimidos con más de 30 días
[Service]
Type=oneshot
ExecStart=/bin/find /var/log -name "*.gz" -mtime +30 -delete

/etc/systemd/system/logrotate-cleanup.timer:

[Unit]
Description=Limpieza semanal de logs
[Timer]
OnCalendar=Sun *-*-* 04:00:00
Persistent=true
[Install]
WantedBy=timers.target

Reinicio de servicio si se cae

# /etc/systemd/system/mi-app-restart.service
[Service]
Type=oneshot
ExecStart=/bin/systemctl restart mi-app.service
# /etc/systemd/system/mi-app-restart.timer
[Timer]
OnBootSec=60
OnUnitActiveSec=300

Este timer corre 60 segundos después del boot y cada 5 minutos desde la última activación. Útil para “asegurar que el servicio esté corriendo”.

Debugging

Ver el estado de un timer

systemctl status mi-tarea.timer
systemctl list-timers --all

Ver el log de la última ejecución

journalctl -u mi-tarea.service -n 50 --no-pager

Probar manualmente

sudo systemctl start mi-tarea.service

Si funciona manual pero no automática, el problema es el calendar — validalo con systemd-analyze calendar.

Cron en debugging

# Mandar todo a un log
*/5 * * * * /script.sh > /tmp/cron.log 2>&1

Después:

tail -f /tmp/cron.log

Preguntas frecuentes

¿Por qué Cron y systemd timers en Linux: automatiza todo en 2026 es relevante para sysadmins Linux?

Forma parte del flujo diario de administración. Los conceptos explicados se aplican directamente a servidores en producción y resuelven problemas reales que enfrentan sysadmins hispanohablantes.

¿Qué necesito para empezar con Cron y systemd timers en?

Distribución Linux actualizada (Debian, Ubuntu, RHEL, Fedora o Arch), acceso root, y conexión a internet. Para producción: entorno de staging separado antes de aplicar cambios.

¿Cuáles son los errores más comunes con Cron y systemd timers en?

Los tres más frecuentes: (1) saltar la lectura de logs, (2) aplicar cambios directos en producción sin probar, (3) olvidar permisos y ownership. La documentación y un plan de rollback siempre.

¿Cuándo usar Cron y systemd timers en y cuándo una alternativa?

Esta solución es ideal para el caso descrito. Alternativas como Docker, Ansible o configuración manual pueden ser mejores según contexto: portabilidad, escala y reproducibilidad son los factores clave.

¿Cómo migro desde una configuración previa a Cron y systemd timers en?

Documentar el estado actual, probar la nueva configuración en staging, validar funcionalmente, y aplicar en producción con rollback plan listo. Los posts de SoyLinux incluyen troubleshooting para los problemas más comunes.

Lee también

Alfonso Moreno | Sysadmin Senior

Soy Alfonso, sysadmin senior con RHCE y más de 10 años administrando sistemas Linux para empresas y proyectos personales. Me especializo en infraestructura, redes, virtualización, monitoring, automation y self-hosting. Sobre SoyLinux.com SoyLinux.com es un blog técnico en español sobre Linux, software libre y self-hosting. Lo mantengo en mi tiempo libre. Áreas de expertise - Linux server administration: RHEL, CentOS, Rocky, Alma, Fedora, Debian, Ubuntu - Network services: Postfix, BIND, Samba, NFS, Squid - Virtualización y containers: KVM, Proxmox, Docker, Podman - Monitoring: Prometheus, Grafana, Zabbix - Automation: Ansible, Bash scripting - Self-hosting: Vaultwarden, Nextcloud, Jellyfin, Immich, Homelab Contacto - Email: [email protected]

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *