¿Cómo evitar que el cron selle?

13

Digamos que tengo varios scripts cron que deben ejecutarse cada 15 minutos. Podría configurarlos para que se ejecuten */15 * * * *, pero luego todos se ejecutan al mismo tiempo. Parece una tontería que el servidor permanezca inactivo durante varios minutos y luego de repente intente ejecutar una docena de scripts al mismo tiempo.

¿Hay alguna forma de ejecutar un script en el minuto 1, 16, 31, 46 y otro en 2, 17, 32, 47?

En otras palabras, quiero que cada script se ejecute cada 15 minutos, pero no me importa que se ejecuten específicamente en las marcas de cuarto de hora.

Botones840
fuente

Respuestas:

7

Estás haciendo esto más difícil de lo necesario. Póngalos todos en la misma línea, separados por punto y coma:

*/15 * * * * command1 ; command 2 ; command 3

Se ejecutará command1, esperará a que termine, luego se ejecutará command2, esperará a que termine, y así sucesivamente.

sombreador
fuente
15

Si hace que su trabajo cron se vea así: 6-59/15 * * * *se ejecutará a las 6, 21, 36 y 51 minutos después de la hora.

Esto puede no funcionar con todas las versiones de cron.

Ladadadada
fuente
14

Podría poner todos los scripts en un directorio, por ejemplo /etc/cron.15m, y luego ejecutar cron

*/15 * * * * run-parts /etc/cron.15m

Eso es asumiendo que tienes el run-partscomando. Está presente en todos los sistemas basados ​​en Debian al menos. Ejecuta todos los programas ejecutables en el directorio nombrado, uno a la vez en orden de lista.

Una desventaja de este método es que si uno de los scripts se cuelga, el resto esperará y no se ejecutará. Si el tiempo de ejecución de todos ellos es superior a 15 minutos, el trabajo comenzará a ejecutarse nuevamente y podría acumular muchos procesos.

Andrew Schulman
fuente
run-partstambién está presente en los sistemas Fedora / Red Hat.
mattdm
9

La forma más sencilla de hacerlo es configurar manualmente los comandos para que se ejecuten cuando desee:

0,15,30,45 * * * * command0
1,16,31,46 * * * * command1
2,17,32,47 * * * * command2
...
14,29,44,59 * * * * command14

O puede escribir un script para generar automáticamente las entradas de crontab apropiadas (que evitan errores tipográficos).

Algunas versiones de cron (probablemente la que está usando) aceptan una sintaxis extendida:

0-59/15 * * * * command0
1-59/15 * * * * command1
1-59/15 * * * * command2
...
14-59/15 * * * * command14
Keith Thompson
fuente
0

Cron no es realmente bueno en lo que intentas hacer. ¿Has considerado escribir un script que actúa como un demonio que básicamente duerme 15 minutos, ejecuta el comando y luego realiza un bucle?

Matt Simmons
fuente
1
Hay un par de problemas potenciales con eso. Una es que si lo hace sleep 300entre cada ejecución del comando, la propia ejecución del comando hará que el tiempo se desvíe; podría ejecutarse cada 15:10 en lugar de cada 15:00. Y si el proceso en segundo plano muere o el sistema se reinicia, a diferencia crond, no se reiniciará automáticamente. Hay formas de "demonizar" un proceso en segundo plano, pero luego se está implementando más o menos crond.
Keith Thompson el
Sí, estoy de acuerdo en que no es una solución perfecta (aunque siempre puedes hacer la tarea en segundo plano con &), pero ahí lo tienes.
Matt Simmons el
1
En cambio, solo haga que cron ejecute un solo script que ejecute todos sus comandos a su vez. De hecho, es una necesidad tan común que hay un script estándar llamado run-partsque se envía con la mayoría de las instalaciones cron para hacer eso específicamente. Ver la respuesta de @ AndrewSchulman.
tylerl
0

Muchas distribuciones tienen /etc/cron.d/cronhourly, por lo que todos los scripts se ejecutan cada hora. Incluso puede especificar el orden comenzándolos con números secuenciales, como 01scriptA 02scriptB: debería ser trivial con el conocimiento cron que ya tiene para fabricar un "cronhourlybyfour" como lo llamamos en la base de distribución de Linux de Smoothwall :)

Palabra de advertencia: esto usa run-parts como se sugirió anteriormente, y run-parts NO le gustan los scripts con a. en el nombre, así que no lo llame "deletehomefolders.sh" llámelo "01deletehomefolders" y asegúrese de comenzar con el # correcto. línea para lo que sea que intente interpretar su script.

Tom Newton
fuente