Artisan Numérique

/système/démarrage/cron/ CRON et la planification de tâches

Difficile de se passer d'un planificateur de tâche, que ce soit pour faire des sauvegardes, vérifier l'intégrité des systèmes, faire le ménage ou bêtement se réveiller le matin. Sous UNIX, le temps c'est le domaine du vénérable CRON.

Principe

CRON est un démon de l'ancien monde, à peu prés aussi vieux qu'UNIX lui-même. Et pour les connaisseurs, sachez qu'il n'a rien à voir avec la divinité cimmérienne, en toute banalité son nom vient du grec "chronos" (χρόνος), le temps.

CRON est un planificateur de tâches dont le rôle est simplement d'exécuter des commandes récurrentes, chacune sur une base de temps donnée (toutes les heures, à une heure particulière chaque jour, au début de chaque mois, etc...).

La version simplifiée

Comme nous allons le voir plus loin, ajouter une tâche dans CRON nécessite de connaître sa syntaxe et de modifier le bon fichier de planning. Cependant sur certaines distribution comme la Mandriva, CRON est pré-configuré de telle sorte que les commandes (ou plus généralement des liens symboliques vers des commandes) contenues dans les dossiers /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly et /etc/cron.monthly, soient exécutées respectivement tous les jours, toutes les heures, toutes les semaines et tous les mois.

Du coup si vous avez seulement besoin de récurrence de ce type (heure, jour, semaine et mois), pas la peine de sortir la grosse artillerie, un simple lien symbolique suffit à planifier la tâche :

lancer la tâche backup tous les jours
rootln -s /usr/bin/backup /etc/cron.daily

vérifier le système toutes les heures
rootln -s /usr/bin/check_system /etc/cron.hourly

Syntaxe des plannings

Bien que pratique, le système par liens symbolique ne répond pas à tous les besoins. Et pour programmer une tâche aussi spécifique que "tous dimanches à l'heure de la messe", il faut mettre un peu plus les mains dans le cambouis.

Les plannings de tâches sont constitués par de simple fichier texte utilisant une syntaxe particulière. Le planning principal est /etc/crontab que très logiquement seul l'utilisateur root peut modifier. Mais pour éviter que ce fichier ne deviennent trop gros et aussi gagner en modularité, il est préférable de créer des micros-plannings dans le dossier /etc/cron.d. La syntaxe sera rigoureusement la même.

Un fichier planning peut commencer par une section de définition de variable. Nous allons grâce à ces variables pouvoir définir dans le contexte d'un même planning : le chemin des exécutable (PATH), le shell à utiliser par défaut (SHELL), le dossier de démarrage (HOME) et l'adresse courriel à utiliser pour envoyer à un tiers le résultat de la commande (MAILTO).

Ces variables sont importante car vous ne savez par exemple jamais quelle est la valeur de la variable PATH au sein d'un CRON, ni quel sera le dossier de démarrage. Elles permettent donc de fixer le contexte de manière fiable.

Dans une autre idée MAILTO définit quant à elle à qui sera expédié le mail qui contient tout ce qui a été "écrit" par une commande (messages, erreurs, etc). Notre premier planning va donc pouvoir ressembler à cela :

#! /bin/sh

# définition des variables spécifiques au planning
# ###################################################
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=mon_mail  @mon_domain.com
HOME=/root

# Une tâche du planning
*/1 * * * * root ls -la
/etc/cron.d/mon_planing

Si votre système est correctement configuré, vous devriez dans la minute qui suit (les plannings sont automatiquement pris en compte) recevoir par mail à l'adresse mon_mail@mon_domaine.com le contenu du dossier /root (cf la variable HOME). Et ce, toutes les minutes... Lorsque vous aurez constaté que cela fonctionne, vous pouvez éditer à nouveau ce planning pour mettre la ligne qui lance la commande ls en commentaire en ajoutant un # en tête.

Comme vous le voyez le fichier planning contient une ligne par tâche planifiée. Chaque ligne est d'abord composée de 5 champs permettant de déterminer le moment du lancement. Suit ensuite l'identifiant l'utilisateur qui sera utilisé pour lancer cette commande, puis la commande elle-même comprenant tout ce qui se trouve après l'identifiant de l'utilisateur. Chaque champs est séparé par des espaces ou des tabulations.

Les 5 champs qui définissent le moment du lancement sont :

minutes Une valeur numérique allant de 0 à 59. heure Une valeur numérique allant de 0 à 23. jour du mois Une valeur numérique allant de 1 à 31. mois Une valeur numérique allant de 1 à 12. jour de la semaine Une valeur numérique de 1 à 7.

Pour les deux derniers champs, la dernière valeur (12 et 7) et 0 sont généralement synonymes mais il est plus simple de ne pas trop y compter. Enfin ces valeurs peuvent aussi être les 3 premières lettres du mois ou du jour de la semaine. Mais là aussi, d'un UNIX à l'autre, c'est de l'anglais ou du français. De plus certains ne prennent pas en charge cette notation pour les listes et les intervalles (voir plus loin).

Chaque champ peut prendre une valeur précise, ou un intervalle de valeur. L'intervalle le plus simple est * signifiant "tout". Ainsi pour lancer une tâche tous les mois, toutes les semaines, tous les jours et à la 2ième minute de chaque heure, cela donne :

02 * * * * gaston /usr/bin/ma_command
/etc/cron.d/exemples

Il est aussi possible de spécifier une liste de valeur en séparant chacune par une virgule. Par exemple pour lancer la même commande que plus haut mais à la 2ième et 42ième minute :

02,42 * * * *  gaston /usr/bin/ma_command
/etc/cron.d/exemples

L'étoile spécifie un intervalle complet, mais nous pouvons aussi utiliser un intervalle restreint. Par exemple une commande lancée la 2ième minute de chaque heure mais de cette fois de 10h du matin à 6h du soir, cela donnerait :

02 10-18 * * *  gaston /usr/bin/ma_command
/etc/cron.d/exemples

Et comme pour les valeurs simples, vous pouvez définir des listes d'intervalles. Par exemple si l'on veut exclure l'heure du déjeuné, cela nous fait deux intervalles :

02 10-12,14-18 * * * gaston /usr/bin/ma_command
/etc/cron.d/exemples

Dernier point, il est possible de dire des choses du genre "toutes les deux heures" en ajoutant un pas à l'intervalle sous la forme intervalle/pas. Pour par exemple effectuer une tâche toutes les 15 minutes, nous affecterons le pas "15" à l'intervalle complet *, soit :

*/15 * * * * gaston /usr/bin/ma_command
/etc/cron.d/exemples

Cette notation de "pas" ne change en rien les propriétés de l'intervalle. Il est donc possible, de faire des listes d'intervalles avec pas. Par exemple toutes des 2 h, de 8h à 12h et de 14h à 18h, à la 2ième minute se note :

2 8-12/2,14-18/2 * * * gaston /usr/bin/ma_command
/etc/cron.d/exemples

Une fois que l'on a mémorisé les différents motifs (valeur, intervalle, liste et pas), l'ajout de nouvelles tâche est très simple. Par exemple pour envoyer un mail tous les jours ouvré à 1h du matin cela nous donne :

0 1 * * 1-5 trichelieu echo "Il est une heure,% tout va bien !!" | mail -s "Rapport" compagnie@son_domaine.net
/etc/cron.d/tour_de_garde

A noter que le caractère % dans la commande est automatiquement changé en "retour chariot". Pour un vrai %, il faut taper \%.

CRON utilisateur

/etc/crontab ou /etc/cron.d ne sont accessible qu'à root. Il est cependant offert à chaque utilisateur la possibilité de disposer de sa propre planification de tâche qui sera alors stockée en /var/spool/cron/nom_utilisateur.

Ne pouvant pas éditer cela directement, il doit utiliser la commande crontab

crontab -l Vérifier si une table existe déjà et la lister si c'est le cas. crontab -e Éditer la table avec vi. Si cet éditeur ne vous plaît pas, ce qui serait surprenant, faite un export EDITOR=gedit avant. crontab nom_fichier Pour importer une table existante. crontab -r Suppression de la table utilisateur.

A noter que certains utilisateurs peuvent être interdits, ou explicitement autorisés à utiliser leur crontab en modifiant les fichier /etc/cron.allow et /etc/cron.deny.

Conclusion

CRON fait parti de ces concepts UNIX indispensables à maîtriser et que pourtant beaucoup considèrent, à tord, comme complexe. J'espère que ce n'est maintenant plus le cas.