La planification de tache consiste à mettre en œuvre des solutions visant à exécuter automatiquement des scripts, des commandes ou des logiciels à une date et une heure spécifiées à l’avance, ou selon un cycle défini à l’avance.
Cron est un démon utilisé pour programmer des tâches devant être exécutées à un moment précis (source)
Anacron est un programme utilisé pour planifier des tâches à interval régulier sans notion de moment (heure, date)
Sans rentrer dans les détails je vais décrire les programmes cron et anacron et leur configurations (vous trouverez plus précis/complet sur d’autre site), puis je vais me concentrer sur les interaction entre ces 2 programmes.
Cron
Cron est un démon (programme toujours lancée) qui s’appui sur des fichiers de configuration nommés crontab pour déterminer quels programmes/script exécuter à quelle date/heure.
Syntaxe Crontab
Chaque utilisateur possède potentiellement un crontab, ils se situent sous /var/spool/cron/crontabs/[user] et ont la structure suivante :
Les # sont des commentaires, je copie toujours ces lignes de commentaire suivante dans mes crontab, rappelant ainsi la structure du fichier.
########################################################## #minute (0-59), # #| heure (0-23), # #| | jour du mois (1-31), # #| | | mois de l'année (1-12), # #| | | | jour de la semaine (0-6 with 0=Dimanche) # #| | | | | commandes # ########################################################## 0 1 * * * /home/user/bin/sauvegarde.sh 0 */3 * * * /home/user/bin/downloadSerie.sh
On a donc 6 zones séparé par des espaces (ou des tabulations).
Les 5 premières servent à spécifier le moment de l’exécution du programme/script qui est indiqué en zone 6;
Ces 5 zones peuvent prendre
- une valeur fixe : 0 à 59 pour les minutes, 0 à 23 pour les heures, 1 à 12 pour les mois et 0 à 6 pour les jours
- une plage de valeurs : 0-6 dans la zone des heures indique de lancer la tache à minuit, 1h, 2h … et 6h du matin
- une liste de valeurs : 0,15,30,45 dans la zone des minute indique de lancer la tache à l’heure + 0 minute (= HH:00), HH:15, HH:30 et HH:45
- un pas : */15 dans la zone des minute indique de lancer la tache toutes les 15 minutes, ce qui ne coïncidera pas forcement avec les même heure que précédemment. En effet en fonction du l’heure de démarrage du PC et donc l’heure de démarrage du Cron on pourra avoir par exemple HH:07, HH:21, HH:37, HH:52, HH+1:07, etc.
Il existe d’autre syntaxe plus compliqué, on peut combiner les différentes syntaxe mais personnellement je n’en ai jamais eu besoin, voir la page du wiki Mandriva
Edition Crontab
Pour éditer la crontab, il ne faut pas aller éditer le fichier dans /var/spool/cron/crontabs/, mais il faut utiliser la commande :
crontab -e
Rque :
Autres commandes :
crontab -l # affichage crontab -r # suppression
Crontab pour le système
Le système Linux lui-même utilise la planification Cron, ces tâches sont définis dans des Crontabs particulière
- fichier /etc/crontab
- fichiers présents sous /etc/cron.d
Ces crontabs ont une zone supplémentaire (en position 6) qui permet de spécifier le user qui doit lancer le script.
17 * * * * root cd / && run-parts --report /etc/cron.hourly
On verra le contenu par défaut de /etc/crontab dans le chapitre « Interaction Cron/Anacron ».
Anacron
Anacron est un programme « standard » (c’est pas un démon/service), il est lancé :
- au démarrage du système via un script d’init (/etc/init.d/anacron)
- via le crontab système, on verra ce dernier point lors de la description des interaction cron/anacron
Anacron lorsqu’il s’exécute vérifie les taches qu’il à de paramétré, lance celles qui doivent l’être puis s’arrête. Anacron n’est pas un programme résident en mémoire.
Anacron n’est pas installé par défaut (tout du moins sous Ubuntu 9.04), pour ce faire on fera un :
sudo aptitude install anacron
Syntaxe Anacrontab
Anacron se configure via un fichier anacrontab (/etc/anacrontab) qui a le format suivant :
########################################################## #périodicité (jours), # #| délai (minutes), # #| | nom de la tache, # #| | | commandes # ########################################################## 1 5 remind remind anniversaire.txt
Dans l’exemple ci-dessus la commande remind (dont je parlerais plus tard) sera exécutée tous les jours 5 minutes après le démarrage d’anacron.
Si la machine reboot plusieurs fois dans la journée, anacron est exécuté plusieurs fois, afin de ne pas lancer une tache quotidienne à chaque reboot anacron stock la date (format AAAAMMJJ) de sa dernière exécution dans un fichier de « log » portant le nom de la tache et présent dans /var/spool/anacron.
Lorsqu’il parcours les taches qui lui sont affecté, anacron vient donc lire le fichier de « log » correspondant, compare la date du jour, la date de dernière exécution et l’intervalle de la tache et la lance le cas échéant.
Interactions Cron/Anacron
Cron et Anacron sont complémentaires, cron appelle anacron et anacron exécute des taches cron.
Anacron appelle les taches Cron
Sous Ubuntu (9.04), par défaut la crontab système contient ceci que anacron soit installé ou non.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin # m h dom mon dow user command 17 * * * * root cd / && run-parts --report /etc/cron.hourly 25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily ) 47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly ) 52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
Le double pipe (||) est un ou logique ainsi si la première commande echoue, la seconde sera exécuté sinon elle ne le sera pas.
Pour le tester vous pouvez essayer ceci :
test -x /usr/bin/wget || echo "le programme wget n'existe pas" test -x /usr/bin/toto || echo "le programme toto n'existe pas"
run-parts permet d’exécuter tous les scripts présent dans le répertoire passé en paramètre (ici les différents répertoire cron.xxx)
Les scripts présents dans /etc/cron.hourly sont donc exécuté toutes les heures à la 17ème minute, les scripts quotidiens, hebdomadaires et mensuels sont exécutés respectivement à 6h25 (tous les jours), 6h47 (le dimanche) et 6h52 (le 1er du mois) SAUF si anacron est installé.
Auquel cas ce sera anacron qui se chargera de les exécuter, nous allons voir comment.
L’anacrontab sous Ubuntu 9.04 contient par défaut :
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin # These replace cron's entries 1 5 cron.daily nice run-parts --report /etc/cron.daily 7 10 cron.weekly nice run-parts --report /etc/cron.weekly @monthly 15 cron.monthly nice run-parts --report /etc/cron.monthly
On voit ici qu’anacron se charge bien d’exécuter les scripts « Cron » présents dans /etc/cron.daily, /etc/cron.weekly et /etc/cron.monthly respectivement tous les jours, tous les 7 jours et mensuellement.
Cron lance Anacron
Sous Ubuntu 9.04 Anacron lance les taches Cron (sauf les hourly) mais qui lance Anacron.
On a vue qu’Anacron s’exécutait au démarrage du système mais comment cela se passe-t-il si le système ne reboot pas ?
Réponse : Anacron est alors lancé par Cron via un crontab système /etc/cron.d/anacron qui contient :
# /etc/cron.d/anacron: crontab entries for the anacron package SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin 30 7 * * * root test -x /etc/init.d/anacron && /usr/sbin/invoke-rc.d anacron start >/dev/null
Tous les jours à 7h30 Cron vérifie que le script d’initialisation anacron existe et si oui (&& = et logique) le démarre.
Les scripts daily sont donc exécuté à 7h35 (démarrage d’anacron à 7h30 mais il attend 5 minutes), les weekly à 7h40 et les monthly à 7h45, sauf si le PC boot/reboot avant cette heure.
Ceinture et bretelles
Afin d’éviter qu’un script daily/weekly/monthly exécuté par Cron ne le soit de nouveau par Anacron, il y a dans chaque répertoire /etc/cron.xxxx un script nommée 0anacron.
Commençant par zéro ce script est exécuté avant tous les autres du répertoire (par run-parts).
Elle contient ceci :
#!/bin/sh # anacron's cron script # This script updates anacron time stamps. It is called through run-parts # either by anacron itself or by cron. # The script is called "0anacron" to assure that it will be executed # _before_ all other scripts. test -x /usr/sbin/anacron || exit 0 anacron -u cron.daily
Ce script (si anacron est installé) lance anacron pour la tache donnée (daily/weekly/monthly) mais avec le paramètre -u qui fait qu’anacron inscrit la date de dernière exécution dans le fichier de « log » correspondant mais n’exécute pas la tache.
Je penses que ce script n’a raison d’être qu’en de très rare cas (d’où mon titre de chapitre), en effet les scripts daily/weekly/monthly ne sont exécutés que par anacron dès lors que ce dernier est installé, or anacron positionne son flag de dernière exécution dès la fin du job.
Plannifier une tache par Cron en priorité puis par Anacron
Venons en au cas qui m’a fait m’intéresser à Cron et Anacron.
Je veux pouvoir planifier un script par Cron en priorité par exemple pour qu’il s’exécute pendant la nuit à une heure précise, mais je veux qu’Anacron prenne le relai si jamais le PC n’était pas allumé à l’heure dite.
En gros je veux faire l’inverse de ce que fait Ubuntu qui donne la priorité à Anacron.
Voici la solution trouvée :
Dans la crontab de mon utilisateur, j’indique l’heure d’exécution de mon script et j’exécute anacron avec l’option -u pour que le script ne soit pas ré-exécuté para anacron lors d’un reboot dans la même journée ou à 7h30 (heure de déclenchement d’anacron par cron) :
########################################################## #minute (0-59), # #| heure (0-23), # #| | jour du mois (1-31), # #| | | mois de l'année (1-12), # #| | | | jour de la semaine (0-6 with 0=Dimanche) # #| | | | | commandes # ########################################################## 0 1 * * * /home/user/bin/remind.sh ; anacron -u remind
Dans l’anacrontab je crée la tache correspondante :
########################################################## #périodicité (jours), # #| délai (minutes), # #| | nom de la tache, # #| | | commandes # ########################################################## 1 5 remind remind anniversaire.txt
Et voila….
Sources :
Image par mararie sous CC BY-SA
Planifier des tâches pour l’ordinateur : excellent article du wiki mandriva sur cron / anacron et at (planification ponctuelle)
http://doc.ubuntu-fr.org/cron : le wiki Ubuntu pour Cron
http://doc.ubuntu-fr.org/anacron : le wiki Ubuntu pour Anacron
http://www.tuxradar.com/content/automate-linux-cron-and-anacron : utilisation de cron et anacron conjointe