Configuration d'un cron toutes les 30 heures dans Debian

*/30 */30 * * * python /root/get_top.py 

J'essaie d'exécuter un script toutes les 30 heures et 30 minutes. La syntaxe ci-dessus est-elle appropriée pour cela?

Plusieurs personnes m'ont dit que * / 30 n'est pas une valeur valide pour la colonne des heures, car elle est supérieure à 24. Si c'est vrai, comment puis-je créer un cron pour un travail qui devrait être exécuté toutes les 30 heures?

La solution la plus simple serait probablement d'exécuter un cronjob plus fréquemment et d'utiliser un script wrapper pour quitter sans rien faire si le time ne s'est pas écoulé.

Pour déterminer combien de fois vous devez courir, prenez le plus grand facteur commun des limites de cron et de l'intervalle désiré.

Donc, pour «toutes les 30 heures, 30 minutes», ce serait «toutes les 30 minutes» et «toutes les 30 heures», ce serait «toutes les 6 heures» (le plus grand facteur commun de 30 et 24)

Vous pouvez implémenter l'encapsuleur de deux manières:

Tout d'abord, vous pouvez stocker un horodatage dans un file, puis vérifier si la différence de time entre maintenant et l'horodatage stocké est supérieure ou égale à 30 heures et 30 minutes.

Cela semble assez simple, mais a deux pièges potentiels qui compliquent le code:

  1. Analyse en security du file d'horodatage enregistré
  2. Permettre un mouvement vers l'avant et vers l'arrière lors de la comparaison des horodatages, car d'autres events survenus sur le système entraîneront un déplacement de l' intervalle réel .

La deuxième option consiste à ne pas stocker de file d'horodatage et à faire des calculs. Ceci est également théoriquement plus rapide car le kernel peut renvoyer l'heure système sans interroger le disque dur.

Je n'ai pas testé cela pour les fautes de frappe, mais voici le code Python qui a été étendu pour plus de clarté.

 import os, time full_interval = 1830 # (30 hours * 60 minutes) + 30 minutes cron_interval = 30 # 30 minutes minutes_since_epoch = time.time() // 60 allowed_back_skew = (cron_interval * 0.1) sorta_delta = (minutes_since_epoch + allowed_back_skew) % full_interval if sorta_delta < cron_interval: os.execlp('python', 'python', '/root/get_top.py') 

Voici l'idée derrière cela:

  1. Tout comme "une horloge arrêtée est correcte deux fois par jour", la valeur de minutes_since_epoch % full_interval sera inférieure à cron_interval une fois par full_interval .
  2. Nous devons faire une correspondance floue pour tenir count des variations causées par le partage des ressources avec d'autres process.
  3. La façon la plus simple de le faire est d'utiliser [0, cron_interval) comme window à l'intérieur de laquelle une tâche doit tomber pour être exécutée.
  4. Pour tenir count de la gigue dans les deux directions, nous faisons glisser le bord de départ de la window de 10% de sa durée car il est rare qu'il s'exécute trop tard à n'importe quel moment où le système est tellement embourbé que le script wrapper est retardé en appelant time.time() .

Si, comme je le pense, get_top.py est votre propre création, il suffit de coller ceci en haut de la page et de changer le chèque en

 if sorta_delta > cron_interval: sys.exit(0) 

Plusieurs personnes sont correctes. */30 n'est pas valide dans la colonne des heures, parce que (dans n'importe quelle colonne), */n signifie "tout ce qui est divisible par n ". Cela est généralement expliqué comme "chaque n whatevers", mais ce n'est pas réellement correct; Par exemple, si vous mettez */5 dans la colonne des heures, le script sera exécuté à 0:00, 5:00, 10:00, 15:00 et 20:00.

En outre, les colonnes sont indépendantes les unes des autres. Si vous mettez */10 dans la colonne des heures et 2,17 dans la colonne des minutes, le script sera exécuté à 0:02, 0:17, 10:02, 10:17, 20:02 et 20:17.

Je ne connais pas un moyen facile d'exécuter un script toutes les 1830 minutes. Vous pouvez utiliser le script pour se replanifier dans 1830 minutes en utilisant la command at , mais ce n'est pas très robuste.

Voici une méthode pour faire ce que vous voulez avec la mise en garde qu'il fonctionnera toutes les 30 heures de l'époque d'Unix.

 0 * * * * [ $(( $(date +%s) / 360 % 30 )) -eq 0 ] && your_command 

Cela va s'exécuter toutes les heures, en effectuant un calcul pour déterminer si cette heure est divisible par 30. Si c'est la division modulo ( % 30 ) renvoie un 0, ce qui signifie que nous sums dans une situation de 30 heures. Si tel est le cas, votre command ( your_command ) s'exécutera.

Comme d'autres l'ont mentionné, vous ne pouvez pas faire ce que vous voulez en utilisant */30 puisque ces valeurs dépassent la valeur de ce champ de time particulier dans cron.

Vous pouvez ajuster l'exemple ci-dessus si vous devez l'incliner de 30 minutes en ajustant le cron (par exemple en utilisant 30 au lieu de 0) ou en ajoutant 30 au bloc conditionnel.