El script funciona perfectamente cuando escribe su nombre. Programado en crontab, no pasa nada: ni archivo de respaldo, ni correo, ni error. Una tarea cron que no se ejecuta es uno de los pequeños acertijos más comunes de la administración de Linux, y la causa casi nunca es cron en sí. Es la diferencia entre su shell interactivo y el entorno mínimo que cron da a cada tarea. Estas son las causas habituales, en el orden en que conviene revisarlas, y cómo crear tareas programadas en las que realmente pueda confiar.
1. ¿La tarea cron no se ejecuta? Empiece por el entorno
Cron inicia las tareas con un entorno mínimo. No lee .bashrc ni .profile, y el PATH de cron predeterminado es solo /usr/bin:/bin. Un comando en /usr/local/bin o /usr/sbin, o una herramienta instalada solo para su usuario, sencillamente no se encuentra. Las variables de entorno de cron también son una lista corta: una contraseña de base de datos exportada en su perfil, un ajuste de proxy o de idioma en el que confía de forma interactiva no estarán allí.
Las soluciones: use rutas completas para los comandos del script, defina PATH al principio del crontab o del script y cargue cualquier configuración que la tarea necesite desde un archivo que el script lea explícitamente. Para ver exactamente lo que cron proporciona, programe una tarea única que escriba la salida de env en un archivo en /tmp y compárela con la de su propio shell.
2. La tarea se ejecuta con sh, no con Bash
A menos que el crontab defina SHELL, cron ejecuta cada línea de comando con /bin/sh. En Debian y Ubuntu eso es dash, un shell más pequeño que no entiende funciones de Bash como arreglos, pruebas con doble corchete o el comando source. Empiece cada script con una línea #!/bin/bash, hágalo ejecutable y llame al script desde cron en lugar de pegar largas líneas únicas de Bash en el crontab.
3. El crontab no funciona por el propio archivo
- El signo de porcentaje. En una línea de comando de crontab, cron convierte en salto de línea un signo de porcentaje sin escapar. Un formato de fecha pasado directamente al comando date es la víctima clásica. Escape cada uno con una barra invertida o traslade el comando a un script.
- La última línea. Un crontab necesita un salto de línea después de su última entrada, o esa entrada puede ignorarse.
- El campo de usuario. Las entradas de /etc/crontab y /etc/cron.d incluyen un nombre de usuario entre el horario y el comando; los crontab personales editados con crontab -e no. Confundir los dos formatos rompe la entrada.
- Nombres de archivo en los directorios de cron. En sistemas basados en Debian, los scripts de /etc/cron.daily y carpetas similares los inicia run-parts, que omite los nombres de archivo que contienen un punto. Un script llamado backup.sh colocado allí nunca se ejecuta; nómbrelo backup. Los archivos de /etc/cron.d siguen la misma regla de nombres.
- Permisos. Los scripts de esas carpetas deben ser ejecutables, y un script que pertenece a un usuario puede no ser legible para la cuenta con la que se ejecuta la tarea.
4. Se ejecutó, pero no cuando esperaba
Cron sigue la zona horaria del servidor. Muchos servidores en la nube funcionan en UTC, así que una tarea pensada para las 2 a.m. en Los Ángeles en realidad se dispara a primera hora de la tarde, hora del Pacífico, y la diferencia se mueve una hora cuando empieza o termina el horario de verano. Compruebe el ajuste con timedatectl y luego escriba el horario en la zona del servidor o cambie la zona de forma deliberada. Para tareas ligadas al horario comercial, anote la zona horaria en un comentario junto a la entrada.
5. Se ejecutó y falló en silencio: dónde encontrar los registros de cron
De forma predeterminada, cron envía por correo la salida de una tarea a su propietario, lo que no llega a ninguna parte en servidores sin entrega de correo. En las versiones actuales de Debian y Ubuntu, el servicio cron registra en el journal de systemd cada tarea que inicia, así que journalctl -u cron muestra si la tarea llegó a lanzarse. Debian 12 y posteriores ya no instalan rsyslog de forma predeterminada, y por eso /var/log/syslog puede no existir cuando busca los registros de cron. Si la tarea se lanzó pero no produjo nada útil, redirija su salida a un archivo de registro o defina MAILTO con una dirección que alguien lea, y haga que el script informe sus propias fallas.
Cómo lograr tareas programadas confiables
Cuando la tarea ya se ejecuta, unos pocos hábitos hacen que siga funcionando. Son lo que separa a los scripts de shell personalizados que se pueden olvidar de los que fallan en silencio durante meses, y son las reglas detrás del trabajo de scripts Bash y automatización que realizamos:
- Modo estricto. set -euo pipefail hace que el script se detenga en el primer comando fallido en lugar de continuar con datos faltantes.
- Sin ejecuciones superpuestas. Envolver la tarea en flock -n con un archivo de bloqueo hace que una ejecución lenta se omita en lugar de duplicarse cuando empieza la siguiente.
- Un latido. La tarea informa su éxito a una comprobación de monitoreo al terminar; si el informe no llega, alguien recibe una alerta.
- Temporizadores de systemd para tareas más pesadas. Los temporizadores de systemd registran en el journal, pueden recuperar las ejecuciones perdidas mientras el servidor estuvo apagado con Persistent=true y muestran la última y la próxima ejecución en systemctl list-timers.
Preguntas frecuentes: tarea cron que no se ejecuta
¿Cómo pruebo una tarea cron sin esperar al horario?
Ejecútela con el mismo entorno mínimo: env -i con un PATH mínimo, como el mismo usuario y mediante /bin/sh si eso es lo que usa cron. Si funciona así, funcionará desde cron. También sirve programarla cada minuto por un rato y observar el journal.
¿Por qué mi tarea cron se ejecuta dos veces?
Normalmente porque está programada en dos lugares, por ejemplo en un crontab personal y en /etc/cron.d, o porque la ejecución anterior seguía en marcha cuando empezó la siguiente. Revise crontab -l de cada usuario, además de /etc/crontab y /etc/cron.d, y añada un bloqueo con flock.
¿Por qué mi tarea funciona desde crontab -e pero no desde /etc/cron.d?
Casi siempre por el campo de usuario o por el nombre del archivo. Las entradas de /etc/cron.d necesitan la columna de usuario, y un nombre de archivo con un punto se ignora.
¿Cansado de scripts que solo funcionan cuando alguien los está mirando? Nuestro servicio de scripts Bash personalizados y automatización escribe, prueba y documenta tareas programadas para copias de seguridad, despliegues y verificaciones de estado, y nuestros servicios de scripts Bash también cubren la corrección de scripts escritos por otra persona. Para servicios de automatización en Linux en Los Ángeles y Long Beach, contáctenos con una breve descripción de la tarea y del servidor en el que se ejecuta.




