Exécuter un script via cron toutes les deux semaines

12

J'ai fait pas mal de recherches sur la façon de procéder, et je vois qu'il n'y a pas de moyen direct de gérer un travail tous les jeudis, disons.

En ce moment, je penche vers la création d'un script qui s'exécutera toutes les semaines et touchera un fichier "indicateur" lorsqu'il s'exécutera, et s'il s'exécute et que le fichier est déjà là, pour supprimer le fichier (et ne pas exécuter le action bihebdomadaire).

Ma question est, existe-t-il une autre manière plus élégante ou plus simple d'atteindre cet objectif d'un script bash d'actions s'exécutant toutes les deux semaines automatiquement?

Merci!

dmkmills
la source
1
Au lieu d'un fichier indicateur, vous pouvez utiliser des numéros de semaine ISO. (Par exemple,% V de strftime)
@ Roger: Je suppose que vous voulez dire dans une conditionnelle dans le script.
pause jusqu'à nouvel ordre.
@Dennis: Cela ne doit pas l'être (par exemple, voyez comment ma réponse vérifie en dehors du script), mais mon point principal est que ce serait beaucoup plus simple et ne nécessiterait aucun état dans le système de fichiers. Cependant, j'ai réalisé qu'il avait un inconvénient similaire à la vérification du jour du mois: certaines années ont 53 semaines et certains en ont 52.

Réponses:

11
0 0 * * Thu bash -c '(($(date +\%s) / 86400 \% 14))' && your-script

J'ai utilisé bash pour faire mes calculs parce que je suis paresseux; passer à ce que vous voulez. Je profite du 1er janvier 1970 comme étant un jeudi; pour les autres jours de la semaine, vous devrez appliquer un décalage. Cron a besoin du pourcentage de signes échappé.

Vérification rapide:

function check {
  when=$(date --date="$1 $(($RANDOM % 24)):$(($RANDOM % 60))" --utc)
  echo -n "$when: "
  (($(date +%s --date="$when") / 86400 % 14)) && echo run || echo skip
}

for start in "2010-12-02" "2011-12-01"; do
  for x in $(seq 0 12); do
    check "$start + $(($x * 7)) days"
  done
  echo
done

Notez que j'ai choisi des heures aléatoires pour montrer que cela fonctionnera s'il est exécuté à n'importe quel moment le jeudi, et choisi des dates qui traversent les limites de l'année et incluent des mois avec 4 et 5 jeudis.

Production:

Thu Dec  2 06:19:00 UTC 2010: run
Thu Dec  9 23:04:00 UTC 2010: skip
Thu Dec 16 05:37:00 UTC 2010: run
Thu Dec 23 12:49:00 UTC 2010: skip
Thu Dec 30 03:59:00 UTC 2010: run
Thu Jan  6 11:29:00 UTC 2011: skip
Thu Jan 13 13:23:00 UTC 2011: run
Thu Jan 20 20:33:00 UTC 2011: skip
Thu Jan 27 16:48:00 UTC 2011: run
Thu Feb  3 17:43:00 UTC 2011: skip
Thu Feb 10 05:49:00 UTC 2011: run
Thu Feb 17 08:46:00 UTC 2011: skip
Thu Feb 24 06:50:00 UTC 2011: run

Thu Dec  1 21:40:00 UTC 2011: run
Thu Dec  8 23:24:00 UTC 2011: skip
Thu Dec 15 22:27:00 UTC 2011: run
Thu Dec 22 02:47:00 UTC 2011: skip
Thu Dec 29 12:44:00 UTC 2011: run
Thu Jan  5 17:59:00 UTC 2012: skip
Thu Jan 12 18:31:00 UTC 2012: run
Thu Jan 19 04:51:00 UTC 2012: skip
Thu Jan 26 08:02:00 UTC 2012: run
Thu Feb  2 17:37:00 UTC 2012: skip
Thu Feb  9 14:08:00 UTC 2012: run
Thu Feb 16 18:50:00 UTC 2012: skip
Thu Feb 23 15:52:00 UTC 2012: run

la source
2
Secondes depuis l'époque est intrinsèquement en UTC, tandis que cron s'exécute en heure locale. Si le fuseau horaire de votre système n'est pas UTC, cela entraînera de la confusion. ("Pourquoi ça ne marche pas? Oh, c'est déjà vendredi en UTC"). L'existence de l'heure d'été rend ce problème beaucoup plus difficile (mais pas impossible, car la date vous indique le décalage UTC actuel)
derobert
5

Une façon pourrait être d'utiliser l' atutilitaire si vous utilisez Linux. Vous pouvez mettre ceci à la fin de votre script:

at X + 2 weeks -f myscript

X est l'heure à laquelle vous souhaitez exécuter votre script. Pour initialiser, il suffit d'appeler atà l'heure à laquelle vous souhaitez l'exécuter la première fois, puis l'instruction ci-dessus continue de renouveler votre appel planifié.

gvkv
la source
Si cela doit être une solution à long terme, je ne recommanderais pas d'exécuter cela, mais je créerais une fonction dans le script qui déterminerait si elle doit fonctionner
Paul
3

Si vous pouvez utiliser anacronle système, les choses seront beaucoup plus simples. Pour l'utiliser, anacronvous devez l'avoir installé et vous devez également avoir un accès root. Il ne fonctionne pas sur les systèmes plus anciens (c'est-à-dire RHEL 5.x), les anciennes versions d'Ancron ne fonctionnent qu'au démarrage. Il fonctionne avec les systèmes plus récents (c'est-à-dire RHEL 6.x).

Avec anacron, on peut planifier des travaux d'une manière plus flexible, par exemple exécuter un travail X une fois par semaine. Exécute également les anacrontravaux lorsque l'ordinateur devient disponible, c'est-à-dire que vous n'avez pas à prendre en compte le moment où le système est en marche ou en panne.

Pour exécuter un script toutes les deux semaines, vous devez ajouter une ligne similaire à la suite de / etc / anacrontab:

14 5 myScript script.sh

Jetez un œil à la page de manuel pour plus de détails.

memin
la source
L'utilisation anacronest clairement la solution la plus propre de l'OMI (à moins qu'elle n'ait des conséquences indésirables pour certaines personnes).
janvier 2010
0

Je ne sais pas s'il existe une façon plus élégante de définir la semaine sur deux, mais cela peut fonctionner pour vous.

00 06 1-7,15-21 * * test `date +\%a` = Thu && /path/to/script

Cela lancera le script à 6h00 le premier et le troisième jeudi du mois.

pferate
la source
2
Cela finirait par sauter une semaine s'il y a un mois avec 3 jeudis, cependant.
David Z
1
Y a-t-il un mois qui n'a que 3 jeudis? Bien que je puisse le voir sauter une semaine s'il y a 5 jeudis. Il peut être mis à jour 1-7,15-21,29-31, mais il fonctionnerait consécutivement s'il y avait des matchs pour le dernier set ...
pferate
1
Par 3 jeudis, voulez-vous dire 3 jeudis pour que le script s'exécute et non pas 3 jeudis au total? Je l'ai peut-être mal lu la première fois.
pferate
0

Je l'exécuterais chaque semaine et ferais vérifier le script pour voir si le numéro de semaine est un nombre impair: si oui, quittez.

Cela nécessiterait plus de réflexion pour fonctionner de décembre à janvier.

Peut-être que le script a défini un fichier d'indicateur "dernière exécution réussie". Lorsque le script se lance, vérifiez que le fichier indicateur a été modifié pour la dernière fois il y a 14 jours.

glenn jackman
la source