Saltar al contenido
HERRAMIENTA SERVIDOR

Verificador crontab: archivo entero y zona horaria

El archivo entero de una vez, no línea por línea. Con aviso cuando varias tareas caen en el mismo minuto.

Herramienta

Nadie lee con gusto una crontab que ha crecido durante años. Cinco asteriscos aquí, una barra allá, y detrás un comando que escribió otra persona hace tres años. Pega el archivo entero y cada línea vuelve en lenguaje claro: qué hace, cuándo se ejecuta la próxima vez y dónde estorba a otra tarea.

01: Cómo usarlo

¿Cómo usar esta herramienta?

  1. Ejecuta crontab -l en el servidor y copia toda la salida, incluidos comentarios, líneas vacías y asignaciones como CRON_TZ o MAILTO.
  2. Elige arriba si es una crontab personal o un archivo de /etc/crontab con su columna de usuario, y fija la zona horaria en la que piensas.
  3. Pega todo en el campo grande. El análisis aparece al momento, línea a línea, con la lectura en lenguaje claro y la próxima ejecución.
  4. Lee el bloque de colisiones. Si un instante lleva varias tareas, pulsa calcular propuesta y copia el archivo escalonado.
  5. Para pasar el resultado a otra persona, coge el informe en Markdown al final, o en JSON si lo va a usar un script o un asistente.

¿Qué hace el verificador de crontab?

Coge lo que cron lee de verdad en tu servidor: el archivo entero. Líneas de comentario, líneas vacías, asignaciones como CRON_TZ=, PATH= y MAILTO=, la programación y el comando que va detrás. Nada de eso hay que recortarlo antes. Cada línea que entra se convierte en una línea de resultado: la programación en lenguaje claro, la próxima ejecución en la zona que rige para esa línea concreta y los avisos que le corresponden.

El verificador funciona por completo en tu navegador. Sin subida, sin servidor, sin muro de cookies. Con una crontab eso no es un asunto menor, porque el archivo nombra hosts, rutas de scripts, nombres de bases de datos y de vez en cuando una contraseña que alguien escribió en una línea de comandos porque tenía prisa.

¿Por qué no basta con un verificador de expresiones sueltas?

Porque los errores interesantes viven entre líneas. Una expresión se consulta en segundos y para eso hay buenas herramientas. Ninguna responde a las preguntas que uno tiene de verdad delante de una crontab heredada: ¿está lo mismo programado dos veces? ¿Choca la copia de seguridad con la exportación? ¿El CRON_TZ de arriba sigue cubriendo la línea de abajo? ¿Y por qué no llega ningún correo desde la mudanza del servidor?

Son propiedades del archivo, no de la expresión. Copiar una crontab línea a línea en un campo de una sola fila te enseña cada fila aislada y, justo por eso, ninguna de esas preguntas. El verificador da la vuelta al orden: primero el archivo, después la línea.

¿Qué pasa cuando varias tareas arrancan en el mismo minuto?

Se lo reparten todo. Procesador, disco, red y normalmente la misma base de datos. El caso clásico tiene este aspecto:

0 0 * * * /usr/local/bin/backup-db.sh
0 0 * * * /usr/local/bin/backup-files.sh
@daily    /usr/local/bin/rotate-logs.sh
0 0 * * 1 /usr/local/bin/weekly-report.sh
0 0 * * * /opt/app/bin/reindex.sh

Cinco líneas, cuatro diarias y una semanal. El lunes a medianoche arrancan las cinco dentro del mismo minuto. Sobre el papel es una programación; en la práctica es un pico de carga. Y como @daily no se expande a otra cosa que 0 0 * * *, al ojear el archivo la colisión ni siquiera se ve.

El verificador calcula las próximas ejecuciones de cada tarea y las pone una al lado de la otra. Cuando más de una cae en el mismo instante, lo dice, con la fecha concreta, los números de línea implicados y el peor momento, aquel en el que más tareas arrancan a la vez. Como compara cuándo se ejecutan las cosas y no cómo están escritas, también salen @daily contra 0 0 * * * y la tarea semanal contra las diarias.

¿Cómo escalona la herramienta las horas de arranque?

De un clic y sin tocar el resto del archivo. La primera tarea de cada choque conserva su minuto, las demás se reparten de forma pareja por la hora. Las cinco líneas de arriba pasan a ser el minuto 0, 15, 35, 12 y 5, siguen siendo a medianoche, siguen siendo el mismo día y con el mismo comando. Hora, día y mes no se tocan.

Después la propuesta se comprueba a sí misma. El archivo reescrito se vuelve a calcular entero. Si queda un instante en el que dos tareas siguen coincidiendo, se desplazan más hasta que nada choca. Solo entonces el panel dice que ha salido bien. Las líneas cuyo campo de minuto es una lista o un paso no se mueven automáticamente, porque desplazarlas cambiaría su significado; en su lugar se nombran una a una para que las mires tú.

El resultado es el archivo completo, listo para copiar, con cada comentario y cada asignación exactamente donde estaban. Vuelve directo a crontab -e.

¿Qué zona horaria rige para una tarea cron?

La del sistema, mientras no diga otra cosa. Ni UTC, ni la del navegador, ni la que tenía en la cabeza quien escribió la línea. Confundirlo te deja una tarea que debía ejecutarse a las seis y que de hecho se ejecuta a medianoche, sin que ninguna entrada de registro lo insinúe.

Una línea CRON_TZ=Europe/Madrid lo cambia, pero solo para las líneas de debajo. Ponla en mitad del archivo y las tareas de encima siguen en la zona del sistema. El verificador hace exactamente eso: recuerda la última zona vista mientras baja por el archivo y calcula cada línea en ella. Las líneas con otra zona la llevan escrita a la vista, y el resumen cuenta cuántas zonas distintas contiene un archivo. Dos casi siempre es un descuido.

A eso se suma el cambio de hora. Cuando el reloj salta hacia delante, una tarea dentro de la hora saltada no se ejecuta. Cuando retrocede, se ejecuta dos veces. Las dos cosas son comportamiento documentado y no fallos, pero casi nadie lo sabe antes de la primera facturación duplicada.

¿Por qué cron no encuentra mi script?

Porque cron arranca en un mundo distinto al de tu sesión de acceso. Sin .bashrc, sin .profile, sin nada del entorno que fija tu despliegue, y con un PATH que según crontab(5) suele ser nada más que /usr/bin y /bin. Todo lo que un gestor de versiones, un gestor de paquetes o tu propia compilación dejó en /usr/local/bin o en el directorio personal queda fuera de alcance.

El verificador señala cada comando escrito sin ruta que no pertenezca a esa dotación básica. tar y find no reciben aviso; un cleanup escrito a mano sí. Si hay un PATH= al principio del archivo, el aviso calla, porque entonces la condición se cumple.

Un segundo clásico vive en el propio comando: el signo de porcentaje. En una crontab % no es un carácter corriente. cron corta la línea ahí y empuja el resto a la tarea por la entrada estándar. tar -czf backup-%Y.tgz se convierte en tar -czf backup- y en un archivo que nadie va a buscar. Una barra invertida delante lo arregla. El verificador encuentra el punto y cuenta bien las barras, así que un porcentaje ya escapado no dispara una falsa alarma.

¿A dónde va la salida de una tarea cron?

Al correo, mientras no digas otra cosa. Si una tarea produce salida y no está redirigida, cron se la manda al propietario de la crontab o a la dirección de MAILTO. En servidores sin entrega de correo funcionando desaparece, y nadie se entera.

El verificador separa tres estados, porque sus consecuencias son muy distintas. Sin redirección y sin MAILTO: cada ejecución manda un correo. Con MAILTO="" puesto: la salida se tira, mensajes de error incluidos. Redirigida a > /dev/null 2>&1: todo en silencio, pero a propósito. Un 2>/dev/null suelto no cuenta como redirección, porque solo calla los errores y deja pasar la salida de verdad, justo al revés de lo que se pretendía.

¿Cuál es la diferencia entre crontab -l y /etc/crontab?

La columna de usuario. Una crontab personal tiene cinco campos de tiempo y después el comando directamente. Los archivos del sistema /etc/crontab y todo lo que hay bajo /etc/cron.d meten entre la programación y el comando una columna con el nombre del usuario con el que debe ejecutarse la tarea.

Copiar una línea de uno a otro produce un fallo que se queda callado. En una crontab personal root pasa a ser sencillamente el comando, y cron intenta arrancar un programa llamado root. Por eso eliges arriba el tipo de archivo. En modo personal el verificador señala una línea que se parece sospechosamente a una que aún lleva columna de usuario.

¿Qué no comprueba esta herramienta?

No ve tu servidor. Si un script existe, si es ejecutable, si el usuario tiene permisos y si el servicio está siquiera en marcha no lo puede responder nadie desde aquí. El verificador trabaja con el texto que pegas y con nada más.

Tampoco vigila las ejecuciones. Si quieres saber si una tarea se ejecutó de verdad anoche, necesitas supervisión en el servidor, no una herramienta en el navegador. Y no impide que una ejecución adelante a la siguiente: para eso está un archivo de bloqueo en el script. Aquí solo recibes el aviso de que una tarea arranca lo bastante a menudo como para que ocurra.

Para expresiones sueltas, para Quartz, para AWS EventBridge y para exportar a GitHub Actions o a un CronJob de Kubernetes está la herramienta hermana, el generador de expresiones cron. Revisar un archivo es cosa de aquí. Construir una línea, de allí.

Última actualización:

También le puede interesar