Comment empêcher cron de se ruiner?

13

Disons que j'ai plusieurs scripts cron qui doivent être exécutés toutes les 15 minutes. Je pouvais les mettre à courir:, */15 * * * *mais alors ils courent tous en même temps. Il semble stupide que le serveur reste inactif pendant plusieurs minutes, puis essaie soudainement d'exécuter une douzaine de scripts en même temps.

Existe-t-il un moyen de faire exécuter un script à la minute 1, 16, 31, 46 et un autre à 2, 17, 32, 47?

En d'autres termes, je veux que chaque script s'exécute toutes les 15 minutes, mais je m'en fous qu'ils s'exécutent spécifiquement au quart d'heure.

Boutons840
la source

Réponses:

7

Vous rendez cela plus difficile que nécessaire. Mettez-les tous sur la même ligne, séparés par des points-virgules:

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

Il s'exécutera command1, attendra sa fin, puis s'exécutera command2, attendra sa fin, et ainsi de suite.

abat-jour
la source
15

Si vous faites en sorte que votre tâche cron ressemble à ceci: 6-59/15 * * * *elle s'exécutera à 6, 21, 36 et 51 minutes après l'heure.

Cela peut ne pas fonctionner avec toutes les versions de cron.

Ladadadada
la source
14

Vous pouvez mettre tous les scripts dans un répertoire, disons /etc/cron.15m, puis faire exécuter cron

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

Cela suppose que vous avez la run-partscommande. Il est présent sur tous les systèmes basés sur Debian au moins. Il exécute tous les programmes exécutables dans le répertoire nommé, un par un dans l'ordre des listes.

Un inconvénient de cette méthode est que si l'un des scripts se bloque, tout le reste attendra et ne sera pas exécuté. Si le temps d'exécution de chacun d'eux est supérieur à 15 minutes, le travail recommencera et vous pourriez obtenir beaucoup de processus s'accumulant.

Andrew Schulman
la source
run-partsest également présent dans les systèmes Fedora / Red Hat.
mattdm
9

La façon la plus simple de procéder consiste simplement à configurer manuellement les commandes à exécuter lorsque vous le souhaitez:

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

Ou vous pouvez écrire un script pour générer automatiquement les entrées crontab appropriées (qui évitent les fautes de frappe).

Certaines versions de cron (incluant probablement celle que vous utilisez) acceptent une syntaxe étendue:

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

Cron n'est pas vraiment bon dans ce que vous essayez de faire. Avez-vous envisagé d'écrire un script qui agit comme un démon qui dort en principe 15 minutes, exécute la commande, puis boucle?

Matt Simmons
la source
1
Il y a quelques problèmes potentiels avec cela. La première est que si vous le faites sleep 300entre chaque exécution de la commande, la propre exécution de la commande entraînera une dérive du temps; il peut s'exécuter tous les 15h10 plutôt que tous les 15h00. Et si le processus d'arrière-plan meurt ou que le système redémarre, contrairement à crond, il ne redémarrera pas automatiquement. Il existe des moyens de "démoniser" un processus d'arrière-plan, mais vous êtes à peu près en train de réimplémenter crond.
Keith Thompson
Oui, je suis d'accord que ce n'est pas une solution parfaite (bien que vous puissiez toujours définir la tâche avec &), mais c'est parti.
Matt Simmons
1
Au lieu de cela, laissez simplement cron exécuter un seul script qui exécute tour à tour toutes vos commandes. En fait, c'est un besoin si commun qu'il existe un script standard appelé run-partsfourni avec la plupart des installations cron pour le faire spécifiquement. Voir la réponse de @ AndrewSchulman.
tylerl
0

De nombreuses distributions ont /etc/cron.d/cronhourly, pour laquelle tous les scripts dans sont exécutés toutes les heures. Vous pouvez même spécifier l'ordre en les commençant par des numéros séquentiels, comme 01scriptA 02scriptB - cela devrait être trivial avec les connaissances cron que vous avez déjà pour fabriquer un "cronhourlybyfour" comme nous l'appelons sur la base de distribution Linux de Smoothwall :)

Un mot d'avertissement: cela utilise des run-parts comme suggéré précédemment, et run-parts n'aime pas les scripts avec a. dans le nom, alors ne l'appelez pas "deletehomefolders.sh" appelez-le "01deletehomefolders" et assurez-vous de commencer par le bon #! ligne pour tout ce que vous avez l'intention d'interpréter votre script.

Tom Newton
la source