Tienes */30
el especificador de minutos , eso significa cada minuto pero con un paso de 30 (en otras palabras, cada media hora). Como cron
no se reduce a resoluciones de menos de un minuto, deberá buscar otra forma.
Una posibilidad, aunque es un poco un error (a) , es tener dos trabajos, uno compensado por 30 segundos:
# Need these to run on 30-sec boundaries, keep commands in sync.
* * * * * /path/to/executable param1 param2
* * * * * ( sleep 30 ; /path/to/executable param1 param2 )
Verá que agregué comentarios y los formateé para garantizar que sea fácil mantenerlos sincronizados.
Ambos cron
trabajos realmente se ejecutan cada minuto, pero el último esperará medio minuto antes de ejecutar la "carne" del trabajo /path/to/executable
.
Para otras cron
opciones (no basadas), vea las otras respuestas aquí, particularmente las que mencionan fcron
y systemd
. Probablemente sean preferibles suponiendo que su sistema tenga la capacidad de usarlos (como instalar fcron
o tener una distribución systemd
dentro).
Si no desea usar la solución kludgy, puede usar una solución basada en bucles con una pequeña modificación. Todavía tendrá que administrar mantener su proceso ejecutándose de alguna forma, pero, una vez que esté ordenado, el siguiente script debería funcionar:
#!/bin/env bash
# Debug code to start on minute boundary and to
# gradually increase maximum payload duration to
# see what happens when the payload exceeds 30 seconds.
((maxtime = 20))
while [[ "$(date +%S)" != "00" ]]; do true; done
while true; do
# Start a background timer BEFORE the payload runs.
sleep 30 &
# Execute the payload, some random duration up to the limit.
# Extra blank line if excess payload.
((delay = RANDOM % maxtime + 1))
((maxtime += 1))
echo "$(date) Sleeping for ${delay} seconds (max ${maxtime})."
[[ ${delay} -gt 30 ]] && echo
sleep ${delay}
# Wait for timer to finish before next cycle.
wait
done
El truco consiste en utilizar un sleep 30
pero para iniciarlo en segundo plano antes de que se ejecute su carga útil. Luego, una vez finalizada la carga útil, solo espere sleep
a que termine el fondo .
Si la carga útil tarda n
segundos (donde n <= 30
), la espera después de la carga útil será 30 - n
segundos. Si demora más de 30 segundos, el siguiente ciclo se retrasará hasta que finalice la carga útil, pero ya no.
Verá que tengo un código de depuración para comenzar en un límite de un minuto para hacer que la salida sea inicialmente más fácil de seguir. También aumento gradualmente el tiempo máximo de carga útil para que eventualmente vea que la carga útil excede el tiempo de ciclo de 30 segundos (se genera una línea en blanco adicional para que el efecto sea obvio).
Sigue una ejecución de muestra (donde los ciclos normalmente comienzan 30 segundos después del ciclo anterior):
Tue May 26 20:56:00 AWST 2020 Sleeping for 9 seconds (max 21).
Tue May 26 20:56:30 AWST 2020 Sleeping for 19 seconds (max 22).
Tue May 26 20:57:00 AWST 2020 Sleeping for 9 seconds (max 23).
Tue May 26 20:57:30 AWST 2020 Sleeping for 7 seconds (max 24).
Tue May 26 20:58:00 AWST 2020 Sleeping for 2 seconds (max 25).
Tue May 26 20:58:30 AWST 2020 Sleeping for 8 seconds (max 26).
Tue May 26 20:59:00 AWST 2020 Sleeping for 20 seconds (max 27).
Tue May 26 20:59:30 AWST 2020 Sleeping for 25 seconds (max 28).
Tue May 26 21:00:00 AWST 2020 Sleeping for 5 seconds (max 29).
Tue May 26 21:00:30 AWST 2020 Sleeping for 6 seconds (max 30).
Tue May 26 21:01:00 AWST 2020 Sleeping for 27 seconds (max 31).
Tue May 26 21:01:30 AWST 2020 Sleeping for 25 seconds (max 32).
Tue May 26 21:02:00 AWST 2020 Sleeping for 15 seconds (max 33).
Tue May 26 21:02:30 AWST 2020 Sleeping for 10 seconds (max 34).
Tue May 26 21:03:00 AWST 2020 Sleeping for 5 seconds (max 35).
Tue May 26 21:03:30 AWST 2020 Sleeping for 35 seconds (max 36).
Tue May 26 21:04:05 AWST 2020 Sleeping for 2 seconds (max 37).
Tue May 26 21:04:35 AWST 2020 Sleeping for 20 seconds (max 38).
Tue May 26 21:05:05 AWST 2020 Sleeping for 22 seconds (max 39).
Tue May 26 21:05:35 AWST 2020 Sleeping for 18 seconds (max 40).
Tue May 26 21:06:05 AWST 2020 Sleeping for 33 seconds (max 41).
Tue May 26 21:06:38 AWST 2020 Sleeping for 31 seconds (max 42).
Tue May 26 21:07:09 AWST 2020 Sleeping for 6 seconds (max 43).
Si desea evitar la solución kludgy, probablemente sea mejor. Aún necesitará un cron
trabajo (o equivalente) para detectar periódicamente si este script se está ejecutando y, si no, iniciarlo. Pero el guión mismo maneja el tiempo.
(a) Algunos de mis compañeros de trabajo dirían que los kludges son mi especialidad :-)