Les notes de Joey : utiliser Crontab

Gazette Linux n°151 — Juin 2008

Traduction: Nicolas Provost

Relecture: Deny

Article paru dans le n°151 de la Gazette Linux de Juin 2008.

Article publié sous Open Publication License. La Linux Gazette n'est ni produite, ni sponsorisée, ni avalisée par notre hébergeur principal, SSC, Inc.


Table des matières

Principes de base
Essayez !
Quelques autres exemples
Quelques astuces ou conseils d'utilisation
Les commandes

crontab est une commande très utile pour exécuter des tâches automatiquement à une heure précise, ce qui est susceptible de vous faire gagner du temps pour l'administration d'une machine. Deux autres commandes ont un effet similaire : anacron et at. anacron permet de programmer l'exécution de commandes n'exigeant pas que la machine soit constamment allumée ; anacron utilise des intervalles de temps de type jour, semaine, mois. L'utilitaire at permet d'exécuter une commande à une heure et une date précises, une seule fois, ce qui peut aussi être très pratique. Mais crontab demeure la commande la plus utilisée, de par sa polyvalence et aussi sa souplesse qui permettent de lancer une exécution à n'importe quel moment.

Dans notre université, nous disposons de plusieurs serveurs qui exécutent des scripts de sauvegarde des données critiques durant les heures creuses. Nous avons automatisé ces tâches à l'aide de cron. Par exemple le script de sauvegarde arrête certains services, effectue une sauvegarde des données modifiées, à l'aide de rsync, sur un serveur secondaire, puis lance classiquement une sauvegarde sur un lecteur de bandes, et enfin relance les services stoppés. Il est certain que je suis heureux de ne pas devoir être présent à une heure du matin, quand l'opération doit s'effectuer ! Grâce à cron, la seule chose que j'ai à faire est de charger ou décharger les cartouches de sauvegarde et à consulter mon courrier électronique chaque matin pour m'assurer que tout s'est bien passé. D'autres programmes doivent également s'exécuter régulièrement, et cela me serait bien pénible d'avoir à me rappeler de les lancer chaque jour.

Pour l'administration de votre système, vous devriez également utiliser quelque peu cron. C'est le fichier crontab qui contient la liste des heures d'exécutions programmées et des commandes à lancer. Le système dispose également d'un fichier crontab par défaut, /etc/crontab, qui lui permet d'exécuter des commandes à des moments précis : à heure fixe, quotidiennement, ou à une fréquence hebdomadaire ou mensuelle. Ce fichier peut sembler un peu énigmatique à première vue, mais voyons d'un peu plus près :

[root@localhost ~]# cat /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

# run-parts
01 * * * * root run-parts /etc/cron.hourly
02 4 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly

La première partie du fichier définit simplement certaines variables :

SHELL : cette première ligne spécifie le shell (interpréteur de commandes) à utiliser pour exécuter les lignes de commandes. C'est /bin/sh par défaut.
PATH : comme cron s'exécute en tant que processus shell fils, il est nécessaire soit de spécifier un chemin, soit d'utiliser une directive PATH dans ce fichier. La raison à cela est que nous ne nous connectons pas à l'aide d'une console pour exécuter les commandes, et donc ni .bashrc ni .bash_profile ne sont disponibles pour initialiser des variables d'environnement utiles à ces commandes, à l'image de ce qui se produit quand nous nous connectons comme utilisateur ou administrateur. Il est également important de se rappeler qu'il est absurde, sans console, d'effectuer des sorties à l'écran, l'écran n'étant pas disponible ! Il faut donc s'assurer que les sorties vont bien être enregistrées quelque part.
MAILTO : à la ligne suivante, la directive MAILTO= permet d'envoyer les résultats des tâches programmées au super-utilisateur root. Si cette directive MAILTO= est présente, mais vide, les courriels électroniques émis par cron ne seront purement et simplement pas conservés. Si la directive n'est pas présente, alors les courriels seront envoyés au propriétaire de crontab. Nous verrons un exemple plus loin.
HOME : la ligne suivante permet de spécifier le répertoire personnel utilisé par cron. S'il n'est pas précisé, alors le répertoire personnel du propriétaire sera utilisé tel que mentionné dans le fichier /etc/passwd
# run_parts : cette ligne commentée indique juste le début d'une autre section, bien que run-parts soit une commande qui exécute tous les scripts ou programmes d'un répertoire donné. Il y a même une page de manuel pour cette commande.

Le champ correspondant au moment d'exécution d'une tâche semble poser problème à tout le monde ; jusqu'à ce que vous soyez habitué, cela peut sembler en effet énigmatique. Le reste est plus simple. La colonne user (utilisateur) correspond à l'utilisateur sous lequel la commande run-parts exécutera les programmes du répertoire spécifié. Remarquez que ces répertoires (colonne path) sont nommés de telle façon qu'ils correspondent avec la fréquence d'exécution : hourly = toutes les heures, daily = tous les jours, weekly = toutes les semaines et monthly = tous les mois. Vous pourriez vous contenter de placer vos scripts dans ces répertoires, et ils seraient exécutés selon la fréquence indiquée. Ce n'est pas une bonne idée, parce que vous pouvez oublier qu'ils se trouvent ici. Il est donc préférable d'éditer votre fichier crontab et de créer votre propre tâche, parce qu'il est plus simple dés lors de lister ces tâches programmées et de les paramétrer finement à l'aide de la commande crontab. Rappelez-vous que c'est le fichier crontab du système (il exécute des scripts ou programmes systèmes pour la maintenance), et donc le fichier crontab d'un autre utilisateur sera différent—en fait la structure sera différente : n'essayez pas de reproduire ce cas particulier.

# Time                User      Command       Path

01   *   *   *   *    root      run-parts     /etc/cron.hourly
02   4   *   *   *    root      run-parts     /etc/cron.daily
22   4   *   *   0    root      run-parts     /etc/cron.weekly
42   4   1   *   *    root      run-parts     /etc/cron.monthly

Principes de base

Deux fichiers indiquent quels utilisateurs ont le droit ou non d'utiliser crontab : /etc/cron.allow et /etc/cron.deny. En pratique, souvent seul le fichier /etc/cron.deny est présent, ce qui rend les choses vraiment très simples, et si le nom d'un utilisateur y figure (un utilisateur par ligne) alors il ou elle n'a pas le droit d'utiliser la commande crontab. Si le fichier /etc/cron.allow existe, alors les utilisateurs indiqués dans ce fichier (un utilisateur par ligne) peuvent utiliser la commande crontab

Dans un fichier crontab il y a six champs pour chaque entrée, les champs étant séparés par des espaces ou des tabulations.

  • les cinq premiers champs précisent quand la commande sera exécutée

          Minutes : 0-59
          Heures : 0-23 (format 24 heures)
          Jour : 1-31 (jour du mois)
          Mois : 1-12 (mois de l'année)
          Jour de la semaine : 0-6 (0 correspond à dimanche)
    
  • le sixième champ indique la commande elle-même

Le fichier ressemble à ceci (les commentaires ne sont pas obligatoires, mais constituent un excellent aide-mémoire) :

# minutes(0-59) heure(0-23) jour/mois(1-31) mois(1-12) jour/semaine(0-6)   commande
   34               2           *            *             *               sh /root/sauvegarde.sh

Dans cet exemple, un script de sauvegarde sh /root/sauvegarde.sh (dernière colonne) sera exécuté à 2h34 du matin chaque jour du mois, chaque mois de l'année et chaque jour de la semaine.

Note

cela requiert que la syntaxe du script ci-dessus soit correcte pour Bash sinon il y aura des erreurs. Comme d'habitude avec les scripts, précisez dans l'entête l'interpréteur de commandes à utiliser (#! ...), rendez-le exécutable, et faites-le exécuter en marquant simplement son chemin, ce qui permet de contrôler plus finement l'environnement d'exécution (note de Ben).

Une étoile dans n'importe quelle colonne indique « tout l'intervalle » ; par exemple une étoile dans « minutes » signifie « exécuter à chaque minute ».

Essayez !

Créons une tâche cron, juste pour voir combien cela est très simple. La commande que nous utilisons est crontab -e, qui ouvre une nouvelle session de l'éditeur vi[A] dans laquelle nous configurerons notre tâche cron. Vous pouvez séparer les champs avec le nombre d'espaces que vous voulez, mais je vous conseille de prendre l'habitude de ne mettre qu'un seul espace afin de garder de la place sur la ligne pour le chemin de la commande à exécuter.

[root@localhost ~]# crontab -e

Maintenant saisissez la ligne suivante :

* * * * * /usr/bin/wall "Bonjour de Crontab"

Après l'avoir enregistré, le message suivant s'affichera

crontab: installing new crontab
[root@localhost ~]#

Peu après, un message va s'afficher :

Broadcast message from root (Thu Apr  3 14:52:01 2008):

Bonjour de Crontab

Ce message apparaîtra toutes les minutes, parce que nous avons mis des étoiles dans tous les champs time; si nous ne retirons pas cette tâche crontab, nous serons salués toutes les minutes de notre vie. C'est aussi une bonne démonstration de ce que cron peut faire en cas d'erreur ! Nous devons exécuter crontab -r pour supprimer cette entrée.

[root@localhost ~]# crontab -r

Supposons maintenant que vous devez lancer le serveur web Apache httpd à un certain moment à l'avenir. Nous pouvons utiliser une tâche cron pour cela. Nous devons tout d'abord contrôler que httpd n'est pas en cours d'exécution. Puis nous lancerons une commande date pour obtenir l'heure courante, de façon à ce que nous lancions le service à l'avenir.

[root@localhost ~]# service httpd status
httpd is stopped
[root@localhost ~]# 
[root@localhost ~]# date
Thu Apr  3 15:45:32 MST 2008
[root@localhost ~]#

Nous pouvons maintenant estimer l'heure qu'il sera dans 10 minutes, exécuter crontab -e et écrire un fichier crontab simple en se rappelant bien son format.

# minutes(0-59) heure(0-23) jour/mois(1-31) mois(1-12) jour/semaine(0-6)   commande
  55            15          *               *          *                   /sbin/service httpd start

Pour le moment, placez des étoiles pour le jour, le mois et le jour de la semaine, avec seulement un espace entre ces éléments ; cela ne fonctionne pas avec certaines distributions si vous ajoutez plus d'espaces. Vous devez donc saisir quelque chose comme :

55 15 * * * /sbin/service httpd start

 [root@localhost ~]# crontab -e 
 crontab: Installing new crontab

Si vous faites une erreur, crontab vous le signalera en quittant l'éditeur. Si nous supposons que tout est juste, le serveur web Apache sera lancé dans moins de 10 minutes à partir de maintenant. Vous pouvez utiliser la commande crontab -l pour afficher les tâches à tout moment, pour voir ce qu'il y a dans votre fichier crontab et quand ces tâches seront exécutées :

[root@localhost ~]# crontab -l 
55 15 * * * /sbin/service httpd start

Vous devriez voir quelque chose d'approchant. Ce que cela signifie, néanmoins, c'est qu'il est prévu que >httpd soit lancé tous les jours à une heure précise. De nouveau nous devons lancer la commande crontab -r pour supprimer toutes les entrées du fichier.

[root@localhost ~]# crontab -r

Les possibilités semblent infinies. Il y a aussi quelques variations pour indiquer l'heure : « 20-27 » spécifie un intervalle ; « 3,4,7,8 » correspond à ces valeurs (ou intervalles) particuliers, et « */5 » signifie « de 5 en 5 ». Une autre fonction de cron est d'envoyer par mail, après chaque exécution de tâche, la sortie de la commande exécutée à l'utilisateur qui a configuré la tâche, à moins que cette fonction ne soit désactivée.

Quelques autres exemples

Cette ligne de crontab exécutera la commande toutes les 15 et 30 minutes de chaque heure du mois de mai :

15,30 * *  5 * /usr/bin/command

Pour exécuter un script de sauvegarde tous les dimanche, lundi et mardi à 2h12 du matin, la ligne devrait être :

12 2 * * 0-2 sh /root/script_de_sauvegarde.sh

Pour exécuter un script à la minute 12, toutes les 3 heures, tous les jours :

12 */3 * * * sh /root/le_script.sh

Pour obliger cron à enregistrer la sortie des commandes dans un fichier journal (log), vous pouvez ajouter quelque chose comme cela à la commande :

12 */3 * * * sh /root/le_script.sh >> /root/le_journal_du_script.log 2>&1

Pour que cron supprime le courriel :

12 */3 * * * sh /root/le_script.sh > /dev/null 2>&1

Voici un exemple de sortie cron qui pourrait s'afficher dans le courriel de fin de tâche :

From root@localhost.localdomain  Thu Apr  3 12:08:01 2008
Date: Thu, 3 Apr 2008 12:08:01 -0700
From: root@localhost.localdomain (Cron Daemon)
To: root@localhost.localdomain
Subject: Cron <root@localhost> sh /root/s.sh
Content-Type: text/plain; charset=UTF-8
Auto-Submitted: auto-generated
X-Cron-Env: <SHELL=/bin/sh>
X-Cron-Env: <HOME=/root>
X-Cron-Env: <PATH=/usr/bin:/bin>
X-Cron-Env: <LOGNAME=root>
X-Cron-Env: <USER=root>

test

Quelques astuces ou conseils d'utilisation

  • utilisez toujours des chemins absolus

  • si vous n'êtes pas certain de l'exécution de votre tâche, vérifiez votre courriel

  • supprimez les lignes inutiles associées aux anciennes tâches cron

  • assurez-vous que le démon crond est en cours d'exécution

Les commandes

crontab -e : édite le fichier crontab courant ou en crée un nouveau

crontab -l : affiche le contenu du fichier crontab

crontab -r : efface le fichier crontab

crontab -u : édite le fichier crontab de l'utilisateur

Joey est né à Phoenix et a commencé à programmer à l'âge de quatorze ans sur un Timex Sinclair 1000©. Il espérait pouvoir tirer quelque chose de ce modèle d'ordinateur ancien. Maîtrisant rapidement le BASIC et l'Assembleur, Joey est devenu programmeur en 1990 et a ajouté le COBOL, le Fortran et le Pascal à son répertoire de langages de programmation. Depuis lors, il se passionne pour presque tous les aspects de l'informatique. Il s'est perfectionné et a découvert RedHat Linux© en 2002, quand on lui a donné une version six de RedHat©. Ce fut le début d'une nouvelle passion centrée sur Linux. Actuellement, Joey termine sa formation en gestion de réseau sous Linux et travaille sur le campus pour la RedHat Academy de l'université, en Arizona. Il fait aussi partie de l'équipe de la Linux Gazette comme coordinateur de miroir.

Adaptation française de la Gazette Linux

L'adaptation française de ce document a été réalisée dans le cadre du Projet de traduction de la Gazette Linux.

Vous pourrez lire d'autres articles traduits et en apprendre plus sur ce projet en visitant notre site : http://wiki.traduc.org/Gazette_Linux.

Si vous souhaitez apporter votre contribution, n'hésitez pas à nous rejoindre, nous serons heureux de vous accueillir.



[A] Commentaire de Rick Moen : en toute rigueur, sur la plupart des systèmes, crontab -e lancera l'éditeur défini par les variables d'environnement VISUAL ou EDITOR.