Écrit en | C |
---|---|
Système d'exploitation | Type Unix |
Type |
Utilitaire UNIX (d) Ordonnancement de tâches informatiques Daemon |
cron est un programme qui permet aux utilisateurs des systèmes Unix d’exécuter automatiquement des scripts, des commandes ou des logiciels à une date et une heure spécifiée à l’avance, ou selon un cycle défini à l’avance.
Origine
Le concept de ce programme trouve son origine dans les systèmes Unix de Berkeley et AT&T, puis a été rationalisé par Paul Vixie. L’idée de départ était d’avoir un service qui se réveille chaque minute, analyse un ensemble de fichiers dans un répertoire particulier, et détermine à partir de là si telles commandes shell doivent être exécutées dans ce laps de temps.
Cron
Cron est la troncation de crontab, lui-même la troncation de chrono table qui signifie « table de planification » (en grec, chronos (χρόνος) signifie le temps[1],[2]).
Il s’agit d’une fonctionnalité très utile pour des tâches routinières d’administration système, mais elle peut très bien être exploitée pour tout autre chose. Par exemple, cron peut jouer un fichier ogg tous les jours à sept heures sauf le samedi et le dimanche afin de se réveiller en musique.
cron est un daemon, ce qui, dans le jargon informatique, désigne un programme qui s'exécute en arrière-plan. Le service cron (crond) attend ainsi jusqu’au moment spécifié dans le fichier de configuration (que l’on appelle la crontab) puis effectue l’action correspondante et se rendort jusqu’à l’événement suivant.
Le service cron est lancé par le compte root afin de pouvoir s’adapter à l’identité de chacun des utilisateurs. Sur certains Unix, si on le tue (par la commande kill), il est automatiquement relancé par le système.
crontab
crontab
est le nom du programme sous Unix (et Linux) qui permet d'éditer des tables de configuration du programme cron. Ces tables spécifient les tâches à exécuter et leur horaire d'exécution avec éventuellement une périodicité. Par extension, on appelle souvent cron (ou cron job en anglais) toute tâche lancée à horaire périodique.
Fonctionnement
La commande crontab
modifie un fichier relatif à l'utilisateur. Par sécurité, crontab
vérifie la syntaxe avant de mettre à jour le fichier. Ce fichier se situe dans l'arborescence /var
, par exemple :
/var/spool/cron/crontabs/<utilisateur>
(AIX, HP-UX, Solaris, Debian GNU/Linux et Ubuntu)/var/spool/cron/tabs/<utilisateur>
(SuSE GNU/Linux)/var/cron/tabs/<utilisateur>
(FreeBSD et OpenBSD)/var/spool/cron/<utilisateur>
(Arch Linux, Fedora et CentOS)/usr/lib/cron/tabs/<utilisateur>
(OS X)
Ainsi pour l'utilisateur root
sur une machine Debian, la table cron sera stockée dans /var/spool/cron/crontabs/root
La majorité des systèmes Linux (SuSE, Debian, Red Hat) disposent en plus d'une table cron centralisée dans /etc/crontab
.
On trouve également des dossiers /etc/cron.d
, /etc/cron.hourly
, /etc/cron.daily
, /etc/cron.weekly
et /etc/cron.monthly
qui contiennent les tables cron des différentes parties du système (rotation des journaux, mise à jour de fichiers...).
Pour les postes de travail qui ne fonctionnent pas forcément 24h/24, l'application anacron permet de lancer les commandes qui auraient dû l'être lorsque l'ordinateur était éteint [3].
Utilisation
Lecture de la table
La ligne de commande suivante affiche le contenu de la table cron pour l'utilisateur courant :
$ crontab -l
Cette commande ne permet pas d'afficher la table centralisée (/etc/crontab
).
Modification de la table
La commande suivante permet de modifier la table cron pour l'utilisateur courant :
$ crontab -e
Cette commande a pour effet de lancer l'éditeur par défaut[4] (en général vi
). L'éditeur affiche alors la table actuelle. Lors du premier lancement de crontab
, la table est vierge, éventuellement composée de commentaires d'aide (lignes commençant par le caractère #
).
L'éditeur par défaut se configure à l'aide des variables d'environnement $EDITOR
ou $VISUAL
. Par exemple, pour configurer l'éditeur vim
:
$ export EDITOR=vim
Cette commande ne permet pas non plus de modifier la table centralisée (/etc/crontab
).
Remplacement de la table
crontab
peut aussi écraser la table courante par une nouvelle.
Cette nouvelle table peut être fournie dans un fichier en paramètre :
$ crontab fichier-contenant-la-nouvelle-table.txt
Suppression de la table
La ligne de commande suivante supprime le contenu, sans confirmation, de la table cron pour l'utilisateur courant :
$ crontab -r
Syntaxe de la table
Notation
Chaque entrée de la table (chaque ligne) correspond à une tâche à exécuter et doit respecter cette notation :
mm hh jj MMM JJJ tâche
- mm représente les minutes (de 0 à 59)
- hh représente l'heure (de 0 à 23)
- jj représente le numéro du jour du mois (de 1 à 31)
- MMM représente l'abréviation du nom du mois (jan, feb, ...) ou bien le numéro du mois (de 1 à 12)
- JJJ représente l'abréviation du nom du jour ou bien le numéro du jour dans la semaine :
- 0 = dimanche
- 1 = lundi
- 2 = mardi
- …
- 6 = samedi
- 7 = dimanche (représenté deux fois pour les deux types de semaine)
Pour chaque valeur numérique (mm, hh, jj, MMM, JJJ) les notations possibles sont :
- * : à chaque unité (0, 1, 2, 3, 4…)
- 5,8 : les unités 5 et 8
- 2-5 : les unités de 2 à 5 (2, 3, 4, 5)
- */3 : toutes les 3 unités (0, 3, 6, 9…)
- 10-20/3 : toutes les 3 unités, entre la dixième et la vingtième (10, 13, 16, 19)
Si, sur la même ligne, le « numéro du jour du mois » et le « jour de la semaine » sont renseignés, alors cron exécutera la tâche quand l'un des champs correspond. Par exemple, la ligne suivante indique que la tâche doit être exécutée les vendredis ainsi que le 13 de chaque mois, à minuit :
0 0 13 * 5 tâche
Journal des opérations
La tâche est une commande à exécuter. Si cette tâche écrit sur sa sortie standard ou son erreur standard, alors le daemon crond les envoie par courriel à l'utilisateur correspondant (celui indiqué par le sixième paramètre).
Afin d'éviter que ces informations soient transmises par courriel, il est possible de les rediriger dans des fichiers. Par exemple :
mm hh jj MMM JJJ tâche > fichier-1 2> fichier-2
fichier-1
contiendra la sortie standardfichier-2
contiendra l'erreur standard
Ou pour accumuler les sorties et erreur standards dans un même fichier nommé journal.txt :
mm hh jj MMM JJJ tâche >> /mon/répertoire/journal.txt 2>&1
Raccourcis
Raccourcis | Description | Équivalent |
---|---|---|
@reboot | Au démarrage | Aucun |
@yearly | Tous les ans | 0 0 1 1 * |
@annually | Tous les ans | 0 0 1 1 * |
@monthly | Tous les mois | 0 0 1 * * |
@weekly | Toutes les semaines | 0 0 * * 0 |
@daily | Tous les jours | 0 0 * * * |
@midnight | Toutes les nuits | 0 0 * * * |
@hourly | Toutes les heures | 0 * * * * |
Exemples
Chacun des exemples enregistre l'espace disque libre (commande df) dans le fichier /tmp/df.log
à des horaires différents. Afin de conserver l'historique, ces exemples utilisent la redirection >>
qui permet d'ajouter les nouvelles données à la fin du fichier (si celui-ci existe déjà, dans le cas contraire il sera créé).
Tous les jours à 23 h 30 :
30 23 * * * df >> /tmp/df.log
Toutes les heures, passées de 5 minutes :
5 * * * * df >> /tmp/df.log
Tous les premiers du mois à 23 h 30 :
30 23 1 * * df >> /tmp/df.log
Tous les lundis à 22 h 28 :
28 22 * * 1 df >> /tmp/df.log
Tous les vendredis et tous les 13 de n'importe quel mois à 11 h 22 :
22 11 13 * 5 df >> /tmp/df.log
Tous les vendredis 13 de n'importe quel mois à 11 h 22 :
22 11 13 * * [ `date '+\%w'` -eq 5 ] && df >> /tmp/df.log
Du 2 au 5 de chaque mois à 10 h 12 :
12 10 2-5 * * df >> /tmp/df.log
Tous les jours impairs du mois à 23 h 59 :
59 23 */2 * * df >> /tmp/df.log
Tous les jours ouvrés à 22 heures :
0 22 * * 1-5 df >> /tmp/df.log
Toutes les 5 minutes :
*/5 * * * * df >> /tmp/df.log
Tous les derniers jours du mois (la barre oblique inversée devant % est obligatoire en édition de crontab, contrairement à l'exécution manuelle de la commande) :
0 0 28-31 * * [ `/bin/date +\%d` -gt `/bin/date +\%d -d "1 day"` ] && df >> /tmp/df.log
- Tous les derniers dimanches du mois :
- Première solution : comparer tous les dimanches avec celui de la semaine d'après.
0 0 * * 0 [ `/bin/date +\%d` -gt `/bin/date +\%d -d "7 day"` ] && df >> /tmp/df.log
- Deuxième solution : tester la dernière semaine tous les mois.
0 0 25-31 1,3,5,7,8,10,12 0 my-script.sh
0 0 24-30 4,6,9,11 0 my-script.sh
0 0 22-29 2 0 my-script.sh
- Troisième solution : lancer un script avec le calendrier.
0 0 21-31 * * /bin/script.sh
$ cat /bin/script.sh
#!/bin/sh
#(Pour les OS où `cal -m` met lundi en position 1)
#dernierdimanche=`cal -m | awk '{print $7}' | tail -1`; #(ERREUR lignes vides si $7="")
#CORRECTIF pour tous les OS
dernierdimanche=`cal -m |awk 'BEGIN{p=7};(NR==2 && $1=="di"){p=1};(NF>=p){di=$p};END{print di};'`;
aujourdhui=`date +%d`
if [ $aujourdhui -eq $dernierdimanche ]
then
df >> /tmp/df.log
else
echo "Nous ne sommes pas encore le dernier dimanche du mois."
fi
- Quatrième solution, utiliser fcron.
- Tous les premiers dimanches du mois :
- Première solution : tester tous les dimanches[5] :
0 0 * * 0 [ `date '+\%e'` -le 7 ] && df >> /tmp/df.log
- Autre solution : le script avec calendrier :
0 0 1-7 * * /bin/script2.sh
$ cat /bin/script2.sh
#!/bin/sh
#premierdimanche=`cal -m | awk '{print $7}' | head -3 | tail -1`; #(ERREUR si lundi "")
premierdimanche=`cal -m | awk '(NR==3){print $NF}'`; #(CORRECTIF simple, pour lundi en position 1)
aujourdhui=`date +%d`
if [ $aujourdhui -eq $premierdimanche ]
then
df >> /tmp/df.log
else
echo "Nous ne sommes pas encore le premier dimanche du mois."
fi
Horodatage du fichier de sortie
Les exemples ci-dessus utilisent la redirection >>
afin de créer un journal sur plusieurs exécutions.
Afin, d'écrire dans des fichiers différents, il est possible d'utiliser la commande date
, comme avec l'exemple suivant :
30 23 * * * df > /tmp/df_`date +\%d_\%m_\%Y_\%H_\%M`.log
(le caractère ` (accent grave, U+0060) est produit par la combinaison des touches [Alt Gr
]+[7] sur le clavier AZERTY en France)
Bien entendu, une autre solution est de réaliser l'écriture du fichier dans un script appelle-df.sh
:
#!/bin/sh
JJ_MM_ANNEE_HH_MM=`date +\%d_\%m_\%Y_\%H_\%M`
df > /tmp/df_${JJ_MM_ANNEE_HH_MM}.log
Et de remplacer la table cron précédente par :
30 23 * * * appelle-df.sh
Commandes utiles
Ces commandes ne fonctionnent pas pour toutes les distributions Linux et Unix.
Indique l'horaire de la dernière tâche exécutée pour l'ensemble des utilisateurs :
ls -lut /etc/init.d/cron
Extrait du journal du système les informations concernant la table cron :
grep -w cron /var/log/syslog
Relance le démon cron :
/etc/init.d/cron force-reload
Changements d'heure
Lors du changement d'heure hiver/été, l'heure officielle passe de 2 h à 3 h (selon les règles en vigueur en France). Les tâches programmées entre 2 h 00 et 2 h 59 ne seront donc pas exécutées. À l'inverse, lors du changement d'heure été/hiver, ces mêmes tâches seront exécutées deux fois (à 3 h, il est encore 2 h).
Afin d'éviter ce désagrément, la plupart des systèmes Unix sont configurés pour utiliser le temps universel coordonné (UTC), qui n'est pas sujet à ces règles de changement d'heure.
GNU mcron
mcron n’est pas une implémentation à proprement parler dudit programme mais une évolution majeure codée en langage Scheme[6]. Il supporte non seulement la méthode traditionnelle, mais également des fichiers de configuration écrits en Scheme, ce qui lui confère une certaine souplesse pour définir les tâches à réaliser (il pourrait par exemple prendre en compte la charge système). La nouveauté vient de sa capacité à lire toutes les instructions requises, à traiter celles qui doivent être ensuite exécutées et à se mettre en veille dans le laps de temps imparti. À son réveil, les commandes sont exécutées et le moment du prochain traitement est alors calculé. Les spécifications de ce nouveau programme sont écrites dans un langage de la famille Lisp, ce qui permet le traitement simultané de plusieurs instructions, et une plus grande flexibilité que le format des fichiers de Vixie. Sans compter que les changements apportés aux fichiers crontabs des utilisateurs lui sont directement signalés par le programme crontab, alors que cron doit vérifier /etc/crontab toutes les minutes bien que l’utilisation de ce fichier soit fortement déconseillée et qu’il puisse être désactivé[7]. C’est un logiciel libre distribué par le projet GNU selon les termes de la licence GPL[7].
Source
Certains passages de cet article, ou d'une version antérieure de cet article, sont basés sur l'article Ordonnancer des tâches du site Web Comment ça marche ?. L'article d'origine porte la notice de copyright suivante : « © Copyright 2004 Jean-François Pillou - Hébergé par Web-solutions.fr. Ce document issu de CommentCaMarche.net est soumis à la licence GNU FDL. Vous pouvez copier, modifier des copies de cette page tant que cette note apparaît clairement. ». Depuis, ce site Comment ça marche ? a changé sa licence. Et finalement, l'article original n'est plus disponible.
Notes et références
- ↑ The Unix acronym list
- ↑ ou peut-être dérivé de chronographe (« Configuring cron jobs », sur Drupal.org (consulté le ) : « Cron, which stands for chronograph (…) »), ou encore de Command Run On (Cron)
- ↑ (en) « Cron vs Anacron, what are the differences? »
- ↑ Défini par la variable d'environnement
$EDITOR
ou$VISUAL
- ↑ (en) Cron job -- to execute at every first Sunday of every month
- ↑ https://www.gnu.org/software/mcron/
- 1 2 (en) « GNU mcron », sur directory.fsf.org, FSF,
Voir aussi
Articles connexes
- Anacron
- Fcron
- Commandes Unix
- Ordonnancement de tâches informatiques
- Informatique
- Quartz (OpenSymphony)
Liens externes
- (en) page de manuel Unix (man page)
- (fr) page de manuel Unix (man page en français)
- (en) Introduction à cron
- Programmation des tâches régulières: crontab sur math-linux.com
- La crontab pour les nuls