Comment planifier pour courir le premier dimanche de chaque mois

J’utilise Bash sur RedHat. Je dois programmer un travail cron à 9h00 le premier dimanche de chaque mois. Comment puis-je faire ceci?

Vous pouvez mettre quelque chose comme ça dans le fichier crontab :

 00 09 * * 7 [ $(date +\%d) -le 07 ] && /run/your/script 

La date +%d vous donne le numéro du jour actuel et vous pouvez alors vérifier si le jour est inférieur ou égal à 7. Si c’est le cas, exécutez votre commande.

Si vous exécutez ce script uniquement le dimanche, cela signifie qu’il ne s’exécute que le premier dimanche du mois.

N’oubliez pas que dans le fichier crontab , les options de formatage de la commande de date doivent être supprimées.

Vous devez combiner deux approches:

a) Utilisez cron pour exécuter un travail tous les dimanches à 9h00.

  00 09 * * 7 /usr/local/bin/once_a_week 

b) Au début de once_a_week , calculez la date et extrayez le jour du mois via shell, Python, C / C ++, … et test compris entre 1 et 7 inclus. Si c’est le cas, exécutez le script réel; sinon, sortez en silence.

Une solution de piratage: lancez votre job cron tous les dimanches, mais vérifiez que le script a bien démarré et quittez immédiatement si le jour du mois est> 7 …

Cela fonctionne également avec les noms des jours de la semaine:

 0 0 1-7 * * [ "$(date '+\%a')" == "Sun" ] && /usr/local/bin/urscript.sh 

Mais,

[ "$(date '+\%a')" == "Sun" ] && echo SUNDAY

sera FAIL sur comandline en raison du traitement spécial de “%” dans crontab (également valable pour https://stackoverflow.com/a/3242169/2919695 )

Exécutez une tâche cron le 1er lundi, 3ème mardi, dimanche dernier, tout.

http://xr09.github.io/cron-last-sunday/

Il suffit de mettre le script run-if-today dans le chemin et de l’utiliser avec cron.

 30 6 * * 6 root run-if-today 1 Sat && /root/myfirstsaturdaybackup.sh 

Le script run-if-today ne renverra que 0 (valeur bash pour True) si c’est la bonne date.

MODIFIER:

Maintenant, avec une interface plus simple, un seul paramètre pour le numéro de semaine.

 # run every first saturday 30 6 * * 6 root run-if-today 1 && /root/myfirstsaturdaybackup.sh # run every last sunday 30 6 * * 7 root run-if-today L && /root/lastsunday.sh 

Il convient de noter que ce qui ressemble à l’approche la plus évidente de ce problème ne fonctionne pas .

Vous pourriez penser que vous pourriez simplement écrire une entrée crontab qui spécifie le jour de la semaine comme 0 (pour dimanche) et le jour du mois comme 1-7, comme ceci …

 # This does NOT work. 0 9 1-7 * 0 /path/to/your/script 

… mais, en raison de l’excensortingcité de la façon dont Cron traite les lignes crontab avec un jour et un jour spécifiés , cela ne fonctionnera pas et s’exécutera en fait le 1er, le 2, 3, Les 4, 5, 6 et 7 du mois (quel que soit le jour de la semaine) et tous les dimanches du mois.

C’est pourquoi vous voyez la recommandation d’utiliser un chèque avec date pour [ ... ] définir une règle comme celle-ci – soit en spécifiant le jour de la semaine dans crontab et en utilisant [ et date pour vérifier que le jour du jour month est <= 7 avant d'exécuter le script, comme indiqué dans la réponse acceptée , ou en spécifiant la plage du jour du mois dans crontab et en utilisant [ et date pour vérifier le jour de la semaine avant son exécution, comme ceci:

 # This DOES work. 0 9 1-7 * * [ $(date +\%u) = 7 ] && /path/to/your/script 

Quelques bonnes pratiques à garder à l’esprit si vous souhaitez vous assurer que votre ligne crontab fonctionnera quel que soit le système d’exploitation sur lequel vous l’utilisez:

  • Utilisez = , pas == , pour la comparaison. C’est plus portable, car tous les shells n’utilisent pas une implémentation de [ qui supporte l’opérateur == .
  • Utilisez le spécificateur %u à date pour obtenir le jour de la semaine sous forme de nombre, et non pas l’opérateur %a , car %a donne des résultats différents en fonction de la date exécution des parameters régionaux.
  • Il suffit d’utiliser date , pas /bin/date ou /usr/bin/date , car l’utilitaire de date a différents emplacements sur différents systèmes.

peut-être utiliser cron.hourly pour appeler un autre script. Ce script vérifiera alors s’il s’agit du premier dimanche du mois et de 9 heures du matin, et si oui, lancez votre programme. Cela semble suffisant pour moi :-).

Si vous ne voulez pas que cron exécute votre travail tous les jours ou tous les dimanches, vous pouvez écrire un wrapper qui exécutera votre code, déterminera le premier dimanche suivant et planifiera son exécution à cette date.

Planifiez ensuite ce wrapper pour le premier dimanche suivant du mois. Après cela, il va tout gérer lui-même.

Le code serait quelque chose comme ça (emphase sur quelque chose … pas de vérification d’erreur):

 #! /bin/bash #We run your code first /path/to/your/code #now we find the next day we want to run nskip=28 #the number of days we want to check into the future curr_month=`date +"%m"` new_month=`date --date='$nskip days' +"%m"` if [[ curr_month = new_month ]] then ((nskip+=7)) fi date=`date --date='$nskip days' +"09:00AM %D` #you may need to change the format if you use another scheduler #schedule the job using "at" at -m $date < /path/to/wrapper/code 

La logique est simple pour trouver le premier dimanche suivant. Depuis que nous commençons le premier dimanche du mois en cours, l’ajout de 28 jours nous mettra soit le dernier dimanche du mois en cours, soit le premier dimanche du mois suivant. Si c'est le mois en cours, nous augmentons au dimanche suivant (qui sera la première semaine du mois suivant).

Et j'ai utilisé "at". Je ne sais pas si c'est de la sortingche. L'idée principale est de trouver le premier dimanche suivant. Vous pouvez remplacer le programmateur de votre choix par la suite, car vous connaissez la date et l'heure auxquelles vous souhaitez exécuter le travail (un autre planificateur peut avoir besoin d'une syntaxe différente pour la date).

00 09 1-7 * 0 / usr / local / bin / once_a_week

chaque dimanche des 7 premiers jours du mois