PROFDINFO.COM

Votre enseignant d'informatique en ligne

Section 6 - Crontab

Retour à la page du cours

Cette section expliquera le fonctionnement de crontab, le planificateur de tâches du monde Unix.

6.1 - Le planificateur de tâches

6.2 - Contrôle d'accès à la crontab

6.3 - Modifier le contenu de la crontab

6.4 - Le format d'un fichier de crontab

6.5 - Quelques exercices

6.6 - Jours du mois et jours de la semaine

6.7 - Ouput des commandes lancées par cron

6.8 - L'environnement par défaut

6.1 - Le planificateur de tâches

Il existe une façon de programmer des tâches pour qu'elles soient exécutées à certains moments précis sans besoin d'intervention humaine - c'est souvent ce qui sera fait avec les scripts qu'on aura créés, permettant ainsi une automatisation de tâches complète.  Évidemment le serveur doit être allumé pour que ça puisse se faire mais personne de spécifique n'a besoin d'être logué pour que ces tâches démarrent. Il suffit que le serveur soit en fonction.

Le programme qui s'occupe de démarrer les bonnes tâches au bon moment s'appelle cron.  Il fonctionne en daemon (donc le nom du processus daemon est crond) et il vérifie à chaque minute si une tâche doit être démarrée. 

En théorie, chaque usager peut avoir sa propre table de tâches (appelée crontab) surveillée par le daemon cron.  En pratique, l'utilisation de cron par les utilisateurs est limitée par root, qui peut permettre ou refuser l'accès aux crontabs à chaque utilisateur.  En général, seuls le root et quelques utilisateurs privilégiés dans une entreprise ont réellement besoin d'une crontab.

Retour à la table des matières de la section

6.2 - Contrôle d'accès à la crontab

Il y a trois règles à vérifier pour déterminer si un usager particulier peut utiliser la crontab:

  • Si le fichier /etc/cron.allow existe, il faut que l'usager y soit inscrit pour pouvoir accéder à la crontab (ce fichier contient simplement une liste d'usagers, un par ligne).
  • Si le fichier /etc/cron.allow n'existe pas et que le fichier /etc/cron.deny existe, il ne faut pas que l'usager y soit inscrit pour pouvoir accéder à la crontab (le fichier cron.deny a le même format que cron.allow).
  • Si aucun des deux fichiers /etc/cron.allow et /etc/cron.deny n'existent, deux possibilités selon la configuration et le type du système:
    • seul root a accès à la crontab (c'est le cas avec Fedora)
    • tout le monde a accès à la crontab

Exception:  peu importe l'existence et le contenu des fichiers de contrôle, root a toujours accès de toute façon, bien sûr.

Retour à la table des matières de la section

6.3 - Modifier le contenu de la crontab

Lorsqu'un usager a accès à la crontab, il peut modifier le contenu de sa crontab personnelle grâce à la commande...  (surprise!)...  crontab!

Premièrement, on peut toujours voir le contenu de la crontab en faisant:

crontab –l

Si un usager n'a pas accès à la crontab, cette commande lui dira:  "You are not allowed to use this program".  S'il a accès à la crontab mais que la sienne est vide, la commande lui répondra "no crontab for user".

On peut également la détruire en faisant:

crontab –r

On peut aussi la modifier en faisant:

crontab –e

ce qui appelle l'éditeur par défaut de l'usager (tel que défini par la variable d'environnement EDITOR – par défaut c'est vi) en y chargeant le contenu actuel de la crontab.  Lorsque l'éditeur sauvegarde le fichier modifié, ces modifications seront prises en compte.

On peut décider de travailler dans un fichier (plutôt que d'éditer la crontab directement), puis de passer le fichier à crontab, en faisant simplement:

crontab  <nom du fichier>

Une fois que l'on a mis quelque chose dans notre crontab, son contenu est conservé dans un fichier à notre nom dans /var/spool/cron.  Ces fichiers seront automatiquement repassés à la crontab au démarrage du système.

Seul root peut modifier la crontab d'un autre usager, tel qu'on peut s'y attendre.  Il lui suffit d'utiliser l'option –u suivie du nom de l'usager en question, puis d'utiliser soit –l, -e, -r ou le nom d'un fichier pour consulter ou modifier la crontab d'un autre usager que lui-même. Par exemple:

crontab -u georges -e

Pour obtenir de l'aide sur la commande crontab elle-même, on peut, bien entendu, faire:

man crontab

Retour à la table des matières de la section

6.4 - Le format d'un fichier de crontab

À la base, ce qu'on met dans une crontab est un horaire de démarrage de tâches.  Chaque ligne représente une tâche à démarrer à certains moments et est formatée de la façon suivante:

minute  heure  jour_du_mois  mois  jour_de_la_semaine  commande

Il s'agira simplement de mettre des valeurs à tous ces champs, séparés par des espaces:

  • minute:  un nombre de 0 à 59
  • heure:  un nombre de 0 à 23 (0 étant minuit)
  • jour_du_mois:  un nombre de 1 à 31 (attention aux mois à 28, 29 ou 30 jours!)
  • mois:  un nombre de 1 à 12 (1 étant janvier) ou une abréviation de trois lettres
  • jour_de_la_semaine:  un nombre de 0 à 7 (0 et 7 étant tous les deux dimanche) ou une abréviation de trois lettres
  • commande:  le reste de la ligne représente une commande complète (possiblement avec des paramètres et des redirections) qui doit être exécutée à certains moments.

Il est toujours possible d'utiliser autre chose qu'un simple nombre dans n'importe lequel des champs, si l'on veut qu'une commande soit exécutée à plusieurs moments.  Crontab acceptera donc:

  • Une simple valeur:  1
  • Une plage de valeurs:  8-11
  • Une liste de valeurs:  1,2,5,9
  • Une liste contenant des valeurs et des plages:  1,2,5-9,10-12,17
  • Une plage avec un pas:  0-12/2 (équivalent à 0,2,4,6,8,10,12)
  • Un astérisque:  * (ce qui représente la plage "premier-dernier")
  • Un astérisque avec un pas:  */2 (tout aussi valide puisque l'astérisque est lui-même une plage)

Notez que les champs jour_de_la_semaine et mois acceptent une abréviation de 3 lettres pour représenter respectivement une journée et un mois.  Ce sont évidemment les abréviations anglophones (Sun, Mon, Tue, Wed, Thu, Fri, Sat et Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec).  La casse n'est pas importante.  Par contre, on ne peut pas utiliser ces abréviations dans une liste ou dans une plage, alors elles sont utiles uniquement si on veut utiliser une valeur unique.

À chaque minute, crond regarde la date et l'heure, et s'il trouve un match (en français on dira "une correspondance") dans une crontab, il exécute la commande correspondante, en prenant l'identité de l'usager à qui appartient la crontab.  La commande sera lancée à partir du répertoire maison de l'usager, comme s'il la lançait lui-même. 

Par contre, les fichiers .bash_profile ou .bashrc ne seront pas lus par crond avant, donc si les commandes que vous voulez lancer ont besoin de certaines définitions de variables ou d'alias, vous devez vous arranger pour ne pas les utiliser ou les ajouter à la crontab directement.

En effet, si vous placez des définitions de variables ou d'alias au début de la crontab, elles seront lues avant le démarrage de toute commande, ce qui est parfois indispensable.

Pour obtenir de l'aide sur les fichiers de crontab et leur format, on peut faire:

man 5 crontab

Retour à la table des matières de la section

6.5 - Quelques exercices


Complétez le tableau suivant, contenant la crontab de georges:

 


Entrée de crontab

Effet

0 0 1,15 * * test –n allo.txt

Exécute la commande "test –n allo.txt" à minuit pile, tous les 1 et 15 du mois.  Le fichier allo.txt passé ici en paramètre doit être dans le home de georges.

1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,

33,35,37,39,41,43,45,47,49,51,53,55,57,59 * * * * test2

 

 

Fait la même chose que la ligne précédente (trouvez une notation plus simple)

0 12 1-5,7,10-20/2,27 */2 * date >> dates.txt

 

 

23 1 * * 1-5 forwardmail

 

 

Ajoute la liste des gens branchés au serveur  à la fin du fichier log.txt dans le home de georges, à toutes les demi-heures, tous les jours sauf le dimanche.

* * * * * shutdown –r now

 

27 15 * Jan Thu cleanup

 

0,15,30,45 * * * Mon,Tue,Wed backup

 

Retour à la table des matières de la section

6.6 - Jours du mois et jours de la semaine

Lorsque quelque chose d'autre que * est entré à la fois pour les jours du mois et pour les jours de la semaine, la commande est exécutée aussitôt qu'une journée satisfait un des deux critères (et non les deux).

Par exemple, la ligne suivante:

0 0 1,15 * 5 test

exécutera la commande test à minuit les 1er et 15 de chaque mois, ainsi que tous les vendredis.  Donc la commande test sera exécutée le 1er et le 15 de tout mois, même si ce n'est pas un vendredi, et tous les vendredis, même s'ils ne sont pas des 1 ou des 15.

En ce sens, cette situation représente un cas d'exception puisque habituellement pour que la commande soit lancée, la journée doit répondre positivement à tous les critères.

Retour à la table des matières de la section

6.7 - Output des commandes lancées par cron

Comme les commandes démarrées par cron ne sont pas faites sur un terminal particulier mais bien en background à partir du serveur directement, l'output de ces commandes serait normalement perdu.

Pour remédier à cette situation et s'assurer que rien ne sera perdu, si une commande produit un output (que ce soit sur la sortie standard - stdout - ou sur l'erreur standard – stderr), cet output sera automatiquement envoyé par e-mail à l'usager propriétaire de la crontab ayant généré l'output.

Comme c'est plutôt ennuyant de recevoir des e-mails contenant l'output de nos commandes (et qu'en plus personne ne peut y avoir accès si la personne à qui la crontab appartient n'est pas présente), on s'arrange habituellement pour rediriger l'output significatif dans un fichier de log accessible à tout un groupe.  Si une commande ne génère aucun output que l'on juge bon d'ajouter à un log, on le redirigera alors vers /dev/null où il pourra jouer avec tous les "y" qu'il rencontrera.  N'oubliez pas qu'il y a deux "canaux" de sortie à rediriger (stdout avec > ou 1> et stderr avec 2>).

Retour à la table des matières de la section

6.8 - L'environnement par défaut

Puisque l'on sait que lorsque cron lance une job il ne tient pas compte de l'environnement initial de l'usager, quel environnement utilise-t-il alors?

Il utilise son environnement par défaut, qui est très minimal:

SHELL=/bin/sh
USER=<nom de l'usager>
PATH=/usr/bin:/sbin
PWD=<répertoire courant: le home de l'usager>
SHLVL=1
HOME=<home de l'usager>
LOGNAME=<nom de l'usager>
_=/usr/bin/env

C'est pourquoi on ajoutera souvent des définitions de variables d'environnement à notre crontab. Notez que la variable LOGNAME ne peut pas être redéféinie dans la crontab, contrairement aux autres. Il est également une bonne précaution d'utiliser des chemins complets et absolus pour toutes les commandes et fichiers passés en paramètres ou utilisés dans les redirections.

Retour à la table des matières de la section