Cómo evitar que los cron jobs se superpongan con flock
Actualizada el 16 de octubre de 2026
Cron no revisa si la ejecución anterior terminó. Si un job que se ejecuta cada 5 minutos tarda 7, dos copias se ejecutan al mismo tiempo, y pueden procesar dos veces los mismos datos o bloquearse entre sí. flock, de util-linux, deja que se ejecute solo una a la vez.
Salta la ejecución si la anterior sigue en curso
*/5 * * * * flock -n /tmp/sync.lock /ruta/al/sync.sh
flock toma un bloqueo sobre el archivo y ejecuta el comando. Con -n, si otra ejecución tiene el bloqueo, termina de inmediato sin ejecutarlo. El bloqueo se libera cuando el comando termina, también si falla.
- Usa un archivo de bloqueo por job, el mismo para todas sus ejecuciones.
-
El usuario del crontab tiene que poder crearlo.
/tmpsirve para cualquier usuario; en Debian y Ubuntu,/run/locktambién. - Solo coordina las ejecuciones que comparten el archivo. Los archivos de bloqueo locales en servidores o contenedores distintos no se coordinan entre sí.
Para comprobarlo antes de usarlo en tu job, toma el bloqueo por 30 segundos en una terminal e inténtalo de nuevo en otra:
flock -n /tmp/test.lock sleep 30
flock -n -E 75 /tmp/test.lock echo "se ejecutó"; echo "código de salida $?"
Mientras la primera tiene el bloqueo, la segunda termina con código de salida 75 sin ejecutar echo. Cuando la primera termina, el mismo comando imprime se ejecutó.
Espera en vez de saltar
*/5 * * * * flock -w 120 /tmp/sync.lock /ruta/al/sync.sh
Con -w 120, flock espera hasta 120 segundos el bloqueo. Si la ejecución anterior termina en ese tiempo, esta se ejecuta justo después; si no, termina sin ejecutarse. Sin -n ni -w, espera lo que haga falta, y las ejecuciones de un job lento se acumulan.
Dentro del script
Cuando el job es un script tuyo, puede tomar el bloqueo él mismo:
#!/bin/sh
exec 9> /tmp/sync.lock
if ! flock -n 9; then
echo "La ejecución anterior sigue en curso"
exit 75
fi
# ... el job
El bloqueo dura hasta que el script termina, y la línea del crontab queda como estaba.
Distingue una ejecución saltada de una que falló
Con -n, una ejecución saltada termina con código 1, como muchos errores. -E define otro código, para que los logs y las alertas puedan distinguirlas:
*/5 * * * * flock -n -E 75 /tmp/sync.lock /ruta/al/sync.sh
75 es una convención, el código para “falla temporal, intenta más tarde”: elige uno que tu script no use, para que solo signifique que el bloqueo estaba tomado. El flock de BusyBox, en las imágenes de Alpine, tiene -n pero no -w ni -E: usa la forma dentro del script para elegir el código.
Otros programadores de tareas
- Un timer de systemd no vuelve a iniciar su servicio mientras la ejecución anterior siga activa.
-
Un
CronJobde Kubernetes lo decide conspec.concurrencyPolicy:Forbidsalta la nueva ejecución, yReplacedetiene la que sigue en curso.
Mira las ejecuciones que se superponen
flock evita la superposición, pero no te dice cada cuánto un job tarda más que el tiempo entre ejecuciones. Con las llamadas de CronDrive en la línea, el historial muestra cuándo una ejecución se inicia mientras la anterior sigue en curso, y el job puede alertar de eso.
Pon flock alrededor del comando, entre las dos llamadas. La llamada de inicio va antes de flock, así que CronDrive registra cada intento, también los que flock salta: el historial puede mostrar un intento superpuesto aunque solo se haya ejecutado una copia del script. Ese intento termina con código 75, así que aparece como fallido con código 75, aparte de las fallas reales.
*/5 * * * * curl -fsS -m 10 https://job.crondrive.com/<token>/start/$$; flock -n -E 75 /tmp/sync.lock /ruta/al/sync.sh; curl -fsS -m 10 https://job.crondrive.com/<token>/end/$?/$$