Planifier des tâches pour l'ordinateur
Un article de Wiki de la communauté Mandriva.
[modifier] Que peut faire la planification ?
Vous êtes derrière votre PC Linux, en train de pianoter gaiement (ou en pestant afin de résoudre un problème bizarre ;-)), lorsque soudainement votre disque dur se met à fonctionner et que votre système manifeste des signes d'activité. Quelques minutes plus tard, cette activité s'arrête et tout redevient comme avant. Vous venez tout simplement d'observer l'exécution d'une tâche planifiée, ou d'un job. En termes Unix, un Job est un programme fonctionnant en arrière plan (« background » en anglais), c'est à dire sans nécessiter l'intervention d'un utilisateur.
Mandriva Linux est livrée avec quelques tâches planifiées qui réalisent des actions de maintenance : mise à jour de la base de données pour la commande locate, déplacement des fichiers de logs (journaux) dans le répertoire /var/log (en faisant une rotation des fichiers pour maîtriser l'espace disque consommé), vérification de la sécurité, suppression de la mémoire système des modules non utilisés, etc. Si vous êtes curieux, regardez les répertoires /etc/cron.d, /etc/cron.hourly (tâches effectuées toutes les heures), /etc/cron.daily (tâches effectuées chaque jour), /etc/cron.weekly (tâches effectuées toutes les semaines) et /etc/cron.monthly (tâches effectuées tous les mois) : ils contiennent les scripts qui sont exécutés par les services cron ou anacron, en général via /etc/crontab. Nous reviendrons plus bas sur tout cela.
Bien sûr, vous pouvez aussi profiter vous-même des avantages de ce système, par exemple pour :
- faire des sauvegardes régulièrement
- configurer le système pour qu'il aille chercher les mails toutes les heures
- vous envoyer des messages de type « agenda«
- envoyer des mails d'anniversaire aux bonnes personnes à la bonne date
- supprimer des fichiers temporaires ou des fichiers non utilisés
- planifier des téléchargements, des mises à jour de miroirs
- déconnecter les utilisateurs inactifs
- etc.
En résumé : toute action régulière qui ne nécessite pas d'action directe de la part d'un utilisateur peut être réalisée par votre système Mandriva Linux.
Les quatre commandes suivantes permettent de planifier l'exécution de diverses tâches :
- sleep suspend l'exécution d'un job pour une durée donnée
- at lance un job à un certain moment
- cron lance des jobs à intervalles réguliers
- anacron lance des jobs suivant des critères plus souples en tenant compte de l'extinction éventuelle de la machine,
en outre :
- KAlarm permet de gérer des tâches par l'interface graphique de KDE.
Nous examinerons ici tour à tour ces différents outils.
La commande sleep est toujours disponible sur un système Linux, car elle est souvent utilisée dans les scripts shell. Les paquetages at et anacron pourraient ne pas être installés (vérifiez avec rpm -q at et rpm -q anacron). cron est inclus dans l'installation standard (paquetage vixie-cron).
[modifier] Pour planifier une tâche unique : les commandes sleep et at
[modifier] La commande sleep
La commande sleep est toujours disponible sur un système Linux, car elle est souvent utilisée dans les scripts shell.
À moins que vous n'écriviez vos propres scripts (ou que vous modifiiez des scripts existants), sleep présente un intérêt relativement limité. Dans les scripts, cependant, cette commande joue un rôle important. Sa syntaxe est :
sleep nombre [smhd]
L'unité par défaut est la seconde (s). On peut spécifier un nombre de minutes (sleep 2m), un nombre d'heures (sleep 3h) ou un nombre de jours (sleep 7d).
Exemple : un rappel par fenêtre surgissante
Vous disposez encore de 10 minutes avant de partir. Vous voulez que Linux vous le rappelle.
Entrez cette commande dans un terminal (ou dans le champ ligne de commande d'une fenêtre appropriée de votre gestionnaire de fenêtres) :
(sleep 10m ; gmessage "Allez, file, petite marmotte !!") &
Une fenêtre d'avertissement s'affichera sur votre bureau dans 10 minutes.
Les commandes sleep et gmessage sont, comme il est normal, enchaînées par un point-virgule. Mettre l'ensemble des deux commandes entre parenthèses en fait un « bloc de code » qui sera globalement exécuté à l'arrière-plan grâce à l'esperluette (&) finale, ce qui vous permettra de garder entretemps l'usage de votre console pour d'autres commandes éventuelles.
D'autres moyens de faire apparaître un message sur le bureau à un moment donné seront indiqués à la section KAlarm.
Planifier l'arrêt de l'ordinateur
Quand je suis au lit, le soir, je tiens parfois à me laisser la possibilité de revenir à l'ordinateur sans avoir à tout relancer, mais je ne veux pas pour autant que ma machine reste allumée toute la nuit si je m'endors avant de penser à l'éteindre. Je peux alors taper ceci sur une console (et cela marche, sur la Mandriva, même en étant connecté comme simple utilisateur) :
sleep 90m;halt
et dans une heure et demi (90 minutes), alors que je serai plongé dans mes rêves, l'ordinateur s'éteindra de lui-même...
[modifier] La commande at
La commande at sert à planifier l'exécution d'une tâche (ou « job ») qui sera lancée une seule fois, à un moment que vous aurez choisi. Si l'ordinateur est éteint à ce moment-là, le job sera exécuté au démarrage de la machine. at ajoutera ce « job » à une file d'attente des tâches planifiées, entreposée dans le répertoire /var/spool/at et gérée par atd, le démon de at. Le démon atd doit être activé pour que la commande at fonctionne correctement. Vous pouvez le vérifier, sous root, en tapant ceci :
service atd status
si atd est activé, vous obtiendrez un affichage de ce type :
atd (pid xxxx) est en cours d'exécution...
Vous pouvez aussi vérifier l'activation de atd par l'interface graphique en lançant le Centre de Contrôle de Mandriva (taper mcc en console sous root, ou bien cliquer sur l'icône Configurer votre ordinateur, puis choisir Système->Activer ou désactiver les services système). Si atd est activé, il doit être marqué comme actif...
Voyons maintenant, pour commencer, comment il est possible d'indiquer à atd le moment où la tâche programmée devra être exécutée.
Vous pouvez donner à at une date précise, comme « le 20 septembre 2007 à midi cinq » :
at 12:05 20.09.2007
mais vous pouvez aussi lui donner une date relative (définie par rapport au « présent », c'est-à-dire par rapport au moment où vous lancez la commande at) comme « demain à 14 heures » :
at 2pm tomorrow
- tomorrow signifie « demain » en anglais - notez que 2pm sera « 2 h de l'après-midi » et 2am « 2h du matin » - bien entendu « à 14 heures (aujourd'hui) » pourra s'exprimer ainsi :
at 2pm
ou, de façon équivalente mais beaucoup plus naturelle dans le monde francophone :
at 14:00
comme vous le voyez, il y a souvent plus d'une façon, pour at, de dire la même chose… Mais attention, les jobs définis par l'une ou l'autre des deux commandes at qui précèdent seront exécutés dès que l'horloge marquera 14 heures, le jour même, par conséquent, si la commande est lancée avant 14 h, mais ils seront exécutés le lendemain si la commande est lancée après 14h… bien entendu.
Pour exprimer « dans 5 heures et 25 minutes », s'il est 16 heures au moment où l'on tape la commande, on écrira :
at 04:25pm + 5 hours
dans des cas de ce genre on utilisera donc hours pour « heures », minutes pour… bon, days pour « jours », months pour « mois » (notez que at ne descend pas en dessous de la minute et ne sait pas compter en secondes...). NB : le s du pluriel reste nécessaire même pour l'unité (on écrira donc « + 1 minutes » ou « + 1 hours » etc.).
Mais, dans de tels cas, on peut aussi parfois utiliser plus simplement une forme now + … (now signifie « maintenant » en anglais), « dans cinq minutes » se dira alors :
at now + 5 minutes
Noter cependant qu'on ne peut écrire, pour « dans 5 heures et 5 minutes », quelque chose comme now + 5 hours + 5 minutes : on ne peut avoir qu'un seul argument additif.
Outre les mots clé tomorrow et now, que nous avons vus, ou today que nous verrons plus bas, at permet aussi l'utilisation de midnight pour « minuit » et noon pour « midi » et même teatime (l'heure du thé..) pour 16 h !
La liste des options valides est disponible dans le fichier /usr/share/doc/at-<no_de_version>/timespec.
Pour ajouter un job à la file gérée par at, vous devez toujours procéder ainsi :
|
Vous obtiendrez quelque chose comme ceci :
at heure date <ENTREE>
warning: commands will be executed using (in order) a) $SHELL b) login shell c) /bin/sh
at> commande_1<ENTREE>
at> commande_2<ENTREE>
at> <CTRL d>
job <numéro> at <date> <heure>
Si l'une des commandes produit une sortie écran, la commande at vous la transmettra par mail, si du moins vous avez pris soin de configurer votre Mail local.
Pour connaître la liste des jobs en attente dans la file, avec leur numéro de job et leur date et heure d'exécution prévue, exécutez :
atq
Pour voir le contenu de la commande correspondant à un certain job, tapez
at -c numero_de_job
Pour supprimer un job de la liste, utilisez
atrm numero_de_job
Notez enfin que si vous utilisez fréquemment at avec une même ligne de commande complexe (comprenant par exemple plusieurs commandes enchaînées ou des adresses compliquées) vous pouvez mettre cette ligne de commande dans un fichier et appeler at avec l'option -f qui permet à at de lire la commande incluse dans le fichier indiqué après l'option :
at -f fichier 14:05 tomorrow
Exemple 1 : s'envoyer à soi-même un message de rappel.
Vous devez passer un coup de fil important dans 3 jours à 16 heures. Vous pouvez demander à at de vous envoyer un message une demi-heure avant (votre système de mail local doit être configuré correctement pour que vous receviez le message automatiquement) :
at 03:30pm today + 3 days at> echo "Coup de fil à passer à 16 heures !! " | mail votre_nom@localhost at> <CTRL d>
Remarquez la présence du mot clé today (aujourd'hui). Il n'est pas nécessaire, mais il vous assure que at
commencera à compter à partir d'aujourd'hui, sans se soucier de l'heure
courante. Si vous l'omettez et qu'il est plus de 15h 30 au moment où
vous écrivez la commande, at commencera à compter à partir du lendemain à 15h 30 (comme si vous aviez tapé en fait tomorrow !) et vous recevrez votre message un jour trop tard !
Nota : Le tube | mail votre_nom@localhost n'est normalement pas nécessaire : le message sera automatiquement expédié vers votre compte de mail local.
Exemple 2 : chercher dans quels fichiers on trouve le nom de votre meilleure amie et faire ensuite une sauvegarde avec Unison
at now + 1 hours at> find /home/toto/Documents -type f -exec grep -l 'Marie Val' {} \; 2>/dev/null at> unison -batch doc at> <CTRL d>
Dans une heure (now + 1 hours), la liste des noms des fichiers contenant « Marie Val » sera construite puis envoyée à votre mail local. Et une sauvegarde Unison en mode silencieux (batch) utilisant le profil Unison doc.prf sera lancée : vous en trouverez aussi un compte-rendu dans votre mail local.
[modifier] Comment tenir compte de la charge du système avec la commande batch
L'outil batch fait partie du paquetage at. Les jobs at invoqués par batch sont exécutés si la charge du système est inférieure à 0.8 (vous pouvez obtenir la charge du système à un moment donné - load average en anglais - en invoquant la commande uptime). Cette valeur peut être changée ainsi :
atd -l valeur
La commande batch s'utilise comme at à ceci près qu'on ne lui fournit ni heure ni date. Une utilisation de batch a donc la forme générale suivante :
batch <ENTREE> warning: commands will be executed using (in order) a) $SHELL b) login shell c) /bin/sh at> commande_1<ENTREE> at> commande_2<ENTREE> at> <CTRL d> job <nombre> at <date> <heure>
Les jobs sont exécutés les uns après les autres dès que la charge du système tombe sous la limite imposée.
[modifier] at, batch et la sécurité
La configuration par défaut autorise tous les utilisateurs à utiliser at et batch. Pour exclure certains utilisateurs, il suffit d'ajouter leur nom de login dans le fichier /etc/at.deny. Il est aussi possible de spécifier tous les utilisateurs autorisés en ajoutant leur nom de login dans le fichier /etc/at.allow.
Pour des raisons de sécurité, il peut arriver que le service atd soit désactivé : dans la Mandriva, c'est l'option par défaut (qui reste cependant modifiable) pour les niveaux de sécurité Plus Elevé et Paranoïaque de l'utilitaire de gestion de la sécurité MSEC.
[modifier] Planifier un affichage
Nous avons vu qu'il était possible grâce à la commande sleep de planifier l'affichage d'un message à l'écran. Notez cependant que cette technique n'est utilisable que dans le cadre d'une unique session : quand vous fermerez l'ordinateur la commande perdra tout effet...
Il ne faut malheureusement pas compter sur at, pas plus du reste que sur cron, que nous verrons plus bas, ou même sur anacron que nous verrons également, pour afficher quoi que ce soit : ni message via gmessage ou xmessage, ni sortie standard d'une commande classique ne pourront être visualisés par le biais des jobs de at, cron ou anacron. Pour cela, vous devrez passer par d'autres outils, comme rclock ou KAlarm, évoqué plus bas. Bien entendu, pour les mêmes raisons, at, cron ou anacron ne lanceront pas pour vous à heure fixe une application graphique, telle que Thunderbird, Firefox ou OpenOffice.org.
Rappelez-vous cependant que la sortie écran des commandes invoquées par at, cron et anacron vous est envoyée par courrier électronique, si vous avez pris soin d'installer votre mail local.
[modifier] Planifier l'exécution régulière d'une tâche : le démon crond
[modifier] Introduction
À proprement parler, il n'existe pas de programme cron mais simplement un démon crond, qui est lancé automatiquement au démarrage du système. Il existe aussi une commande crontab qui permet de manipuler les fichiers de configuration de crond. Ces fichiers de configuration sont connus sous l'appellation de crontab.
Depuis longtemps, LinuxConf et Webmin proposent des modules pour configurer le service crond via une interface graphique.
Sous KDE, vous pourrez faire usage de KCron dont vous disposerez après installation du paquetage kdeadmin (taper kcron en console pour y accéder).
Mandriva propose un outil graphique : drakcronat (installez le paquetage du même nom, s'il n'est pas présent sur votre système) qui permet de gérer aisément des tâches crond simples. Une fois le paquetage installé on y accède par Centre de Contrôle Mandriva -> Système -> Planifier les programmes à exécuter périodiquement.
Une bonne connaissance de ce qui suit vous aidera néanmoins, même si vous utilisez ces différents outil. Nota : Au moment où nous révisons cette page (début janvier 2007) drakcronat semble être bogué et inutilisable sous KDE.
Le système crontab, dans Mandriva Linux, comprend deux parties :
- l'ensemble des tâches crond du système est contrôlé, pour l'essentiel, par le fichier de configuration /etc/crontab. Sous la Mandriva, ce fichier détermine le lancement à intervalles réguliers du programme /usr/bin/run-parts. Ce dernier appelle à son tour les scripts stockés dans les répertoires /etc/cron.hourly (tâches à effectuer toutes les heures), /etc/cron.daily (tâches à effectuer tous les jours), /etc/cron.weekly (tâches à effectuer toutes les semaines) et /etc/cron.monthly (tâches à effectuer tous les mois).
Notez que des crontab analogues à /etc/crontab peuvent aussi être placées dans le répertoire /etc/cron.d.
- les fichiers crontab des utilisateurs (y compris root) sont stockés dans le répertoire /var/spool/cron/nom-de-l'utilisateur.
[modifier] Comment est indiqué le moment prévu pour l'exécution de la tâche
Regardons le fichier /etc/crontab afin de nous familiariser avec la syntaxe crond. Dans la configuration par défaut, la fin du fichier se présente ainsi :
01 * * * * root run-parts --report /etc/cron.hourly
02 4 * * * root run-parts --report /etc/cron.daily
22 4 * * 0 root run-parts --report /etc/cron.weekly
42 4 1 * * root run-parts --report /etc/cron.monthly
Nota Bene : Entre le dernier champ donnant une indication de temps et le champ qui contient la commande à exécuter, dans /etc/crontab et dans les éventuelles crontab contenues dans /etc/cron.d, figure l'indication du nom de l'utilisateur (root dans notre exemple) sous l'identité duquel la commande sera exécutée. Ce champ est en revanche absent des crontab d'utilisateurs de /var/spool/cron/nom-de-l'utilisateur.
Chaque ligne commence par une série de 5 champs qui indiquent, dans notre exemple, quand la commande run-parts sera exécutée :
- le premier champ indique la minute (un nombre de 0 à 59)
- le second champ indique l'heure (un nombre de 0 à 23)
- le troisième indique le jour du mois (un nombre de 1 à 31)
- le quatrième indique le mois (soit par un nombre de 1 à 12, soit par un nom court : jan/feb/mar/apr/may/jun/jul/aug/sep/oct/nov/dec)
- le cinquième indique le jour de la semaine (soit par un chiffre de 0 à 7 - le dimanche peut être représenté par le chiffre 0 ou par le chiffre 7, le chiffre 1 représente le lundi etc. - soit par un nom court, à savoir, de dimanche à samedi : sun/mon/tue/wed/thr/fri/sat).
Un astérisque (*) indique une « non condition » qui doit être comprise (selon sa position) comme : « peu importe la minute, l'heure, le mois ou le jour de la semaine ».
Regardons de près la dernière ligne du fichier. On peut y lire : la commande sera exécutée à la 42ème minute de la 4ème heure du 1er jour de chaque mois. Peu importe donc le mois (* dans la 4ème colonne) ou le jour de la semaine (* dans la 5ème colonne).
Voyons quelques exemples :
* * * * * commande1
la commande commande1 sera exécutée toutes les minutes, sans se soucier de l'heure, du jour ou du mois.
* * * * mon commande2
la commande commande2 sera exécutée toutes les minutes, mais uniquement le lundi (mon = Monday = lundi).
Que fait cette commande-là, d'après vous ?
44 14 * 11 wed commande3
Alors ?
La commande commande3 sera exécutée tous les mercredis (wed = Wednesday = mercredi) de novembre (11) à 14h 44.
Il est important de bien comprendre comment le troisième champ (jour du mois) et le cinquième champ (jour de la semaine) sont interprétés, lorsqu'ils sont tous les deux spécifiés.
Supposons, par exemple, que vous changiez la dernière ligne de /etc/crontab pour aboutir à ceci :
42 4 1 * sun commande
On pourrait croire que cela limiterait l'exécution de la commande commande au premier jour de chaque mois à 4h 42 si ce jour est un dimanche (sun). En fait, si les champs 3 et 5 sont différents de *, la commande sera exécutée chaque fois que la condition exprimée par l'un des deux champs est satisfaite. Dans ce cas, par conséquent, elle sera exécutée tous les 1er de chaque mois et aussi tous les dimanches.
Dans une crontab on peut aussi spécifier des plages de valeurs (x-y), des listes (x,y,z) et des valeurs par pas (éventuellement combinées avec des plages, x-y/z). Mais voyons cela sur un exemple :
05-15,30-40/3 8,12,16 * */2 7 commande
Pas facile, n'est-ce pas ? ;-) Voici une méthode de lecture : lorsque vous avez à déchiffrer des règles crond plutôt complexes, lisez les champs de la droite vers la gauche. Ce qui précède signifie donc que :
la commande commande est exécutée :
- les dimanches (7)
- un mois sur deux (*/2), donc en janvier, mars, mai...
- aux 8ème, 12ème et 16ème heures de la journée (8,12,16)
- toutes les minutes de la 5ème à la 15ème minute (05-15)
- puis toutes les 3 minutes entre 30 et 40 (30-40/3).
En janvier 2008, cette commande sera donc exécutée les dimanches 6, 13, 20, et 27, toutes les minutes de 8h 05 à 8h 15 incluses, puis toutes les 3 minutes de 8h 30 à 8h 40, c'est-à-dire à 8h 30, 8h 33, 8h 36 et 8h 39. Idem à la 12ème heure et à la 16ème heure.
Vous voyez à quel point vous êtes maître du temps lorsque vous écrivez dans une crontab !
[modifier] Écrire votre propre table de planification crontab
Pour modifier ou créer votre fichier crontab (le fichier relatif à votre compte utilisateur Linux, fichier qui, je vous le rappelle, sera entreposé dans /var/spool/cron), tapez :
crontab -e
qui ouvre un nouveau fichier de configuration (ou le fichier existant, s'il y en a un) dans un éditeur.
Assez bizarrement, il pourrait arriver que, par défaut, vous ne soyez pas autorisé à éditer votre crontab sous votre identité de simple utilisateur non root. Si c'est le cas, créez, sous root, un fichier texte /etc/cron.allow, où seront énumérés les utilisateurs du système autorisés à éditer leur crontab. Un /etc/cron.allow comme, par exemple :
toto
glin
autoriserait les utilisateurs toto et glin - et eux seuls - à éditer leur crontab.
Une solution alternative serait de créer un fichier /etc/cron.deny qui énumèrerait de la même façon les seuls utilisateurs qui ne seraient pas autorisés à éditer leur crontab. Le plus simple est alors de créer sous root un fichier de ce genre… vide, par la commande :
touch /etc/cron.deny
tous les utilisateurs seront alors autorisés à éditer leur crontab.
Par défaut, crontab utilise l'éditeur vi. Pour utiliser un autre éditeur, par exemple kate, exécutez cette commande avant d'appeler crontab, ou pour un emploi permanent, placez-la dans votre ~/.bashrc :
export EDITOR=/usr/bin/kate
(Cette facilité d'appel à un autre éditeur était boguée sous la Mandriva 2006, elle fonctionne maintenant correctement sous la 2007.) Notez que vous devez donner le chemin complet de l'éditeur : pour savoir quel est exactement ce chemin pour un éditeur donné, taper whereis + nom de l'éditeur, par exemple
whereis kate
vous donnera : /usr/bin/kate.
NOTE Si l'éditeur par défaut vi ne vous est pas familier, notez cependant que les commandes suivantes de vi vous suffiront pour éditer une crontab :
- i vous met en mode « insertion »
- <ESC>:x (touche Echap puis les 2 touches :x) + <ENTREE> sauve le fichier en cours d'édition et quitte l'éditeur
- <ESC>:q! (touche Echap puis les 3 touches :q! ) + <ENTREE> quitte l'éditeur sans prendre en compte les modifications éventuelles.
Notez qu'il existe aussi divers éditeurs graphiques, tels que KCron (inclus dans le paquetage kdeadmin), ou encore l'outil mandrivien drakcronat. Attention, si vous créez une tâche avec de tels outils, votre crontab actuelle (/var/spool/cron/nom_d_utilisateur) sera écrasée : il peut être prudent de commencer par la sauvegarder.
Lorsque vous éditerez votre crontab n'hésitez pas à y mettre des « commentaires », sous forme de lignes commençant pas un dièse (#), qui vous aideront à vous souvenir de la finalité des commandes que vous avez placées dans la table (voir plus bas pour un exemple). Le contenu de ces commentaires ne sera jamais exécuté par crond.
Pas de commentaire en fin de ligne dans une crontab ! Contrairement à ce qui est le cas dans divers langages de programmation et notamment dans le shell Bash, dans une crontab un signe de commentaire (dièse) ne peut être placé qu'en début de ligne, jamais après la commmande.
Les autres options de crontab sont -l et -r :
crontab -l
se borne à afficher le contenu de votre crontab et
crontab -r
détruit votre crontab.
Effacer une crontab ou la commenter ? Plutôt que d'effacer votre crontab, il peut être astucieux de placer un commentaire en tête de toutes les lignes de commande qu'elle contient. Il vous sera ensuite très facile de réactiver tout ou partie des commandes (éventuellement après les avoir modifiées), en supprimant simplement la totalité ou une partie des dièses.
Les commandes qui occupent plusieurs lignes ne sont pas autorisées, à moins de terminer la ligne par le caractère '\' (une convention qui est valable aussi pour les scripts du shell) : ce qui suit le '\' sera alors considéré comme appartenant à la même « grande' ligne ». Vous pouvez aussi mettre une commande longue dans un script et appeler ce script à partir de la crontab.
Si vous voulez éditer la crontab d'un autre utilisateur du système, vous devez passer sous root (utilisez la commande su par exemple) puis utiliser la commande crontab ainsi :
crontab -e -u nom_d_utilisateur
Si la commande exécutée par le démon crond produit un affichage ou si un message d'erreur est engendré, un mail en transmet le contenu au propriétaire de la crontab responsable de l'exécution de la commande. Il faut avoir installé et activé un serveur de mail local comme Postfix pour que le mail arrive à son destinataire. Lorsque le destinataire est root le message doit être redirigé vers le compte de simple utilisateur de l'administrateur, de la façon indiquée à la page du Wiki qui traite du mail local. Il est possible de définir un destinaire du message autre que le destinataire par défaut en assignant une valeur à la variable MAILTO, comme dans cet exemple :
MAILTO=""
0 * * * * job1
MAILTO=jim
0 * * * mon job2
Pour le job1, aucun mail ne sera envoyé (même si le programme échoue). Le mail d'information sera envoyé à l'utilisateur jim pour le deuxième job.
[modifier] Les variables de crond
Nous l'avons vu à l'instant, il est possible d'assigner, au sein d'une crontab, une valeur à certaines variables, qui seront ensuite utilisées comme « environnement » par crond pour exécuter les jobs.
Nous avons mentionné la variable MAILTO qui sert à déterminer le destinataire par défaut du courrier.
Il est aussi possible d'utiliser une variable SHELL pour définir le shell (sh, Bash etc.) utilisé.
On peut également définir une variable PATH, contenant les « chemins » où crond cherchera les commandes à exécuter. On peut même définir une variable HOME qui déterminera relativement à quel « répertoire de travail » seront exécutées les commandes des jobs énumérés dans la crontab.
Chemins absolus ou relatifs dans une crontab : Attention, lorsqu'une commande crontab est exécutée sous l'identité d'un utilisateur, elle ne prend pas en compte tout l'environnement de cet utilisateur et notamment les valeurs de la variable PATH. Par conséquent, vous devez :
- ou bien écrire les commandes (et les éventuels fichiers passés en argument) avec leur chemin absolu (par exemple : si vous êtes l'utilisateur toto, pour lancer le script sauvliens.sh vous écrirez /home/toto/bin/sauvliens.sh, et non simplement sauvliens.sh, même si /home/toto/bin est dans votre PATH d'utilisateur)
- ou bien vous définissez une valeur pour la variable PATH propre à la crontab et vous pouvez utiliser alors des chemins relatifs par rapport aux chemins figurant dans cette variable propre à la crontab (par exemple : si vous placez dans le PATH de la crontab le chemin /home/toto/bin, vous pourrez lancer le script évoqué plus haut en écrivant simplement sauvliens.sh).
Il est enfin tout à fait possible de créer une variable de votre choix, à utiliser ensuite dans les commandes constitutives des jobs, un exemple un peu bête mais illustratif serait ceci :
MESSAGE="Il est l'heure"
0 13 * * * echo "$MESSAGE"
qui vous enverrait chaque jour à 13h un mail contenant le message Il est l'heure…
[modifier] Exemple : compression mensuelle du répertoire des mails envoyés
Vous voulez que cron réalise la compression de votre dossier (ou fichier) sent_mail, que le fichier d'archive ainsi obtenu soit stocké quelque part et que le dossier d'origine soit ensuite vidé. Créez un script comme celui-là :
#! /bin/bash # tar czf $HOME/mail/sent_mail$(date +%b%Y).tar.gz /chemin_du/repertoire_ou_fichier_sent_mail # pour les fichiers mail au format mbox : if $?=0; then echo > /chemin_du/fichier_sent_mail else exit 1 fi # pour les répertoires de mails au format mh : if $?=0; then rm -f /chemin_du/repertoire_sent_mail/* else exit 1 fi
Avant de revenir à cron, quelques mots d'explication sur ce script seront sans doute bienvenus...
Notez d'abord que la variable d'environnement HOME contient le chemin de votre répertoire personnel (par exemple, /home/toto).
L'utilisation de if évite de supprimer le fichier ou le répertoire sent_mail si la commande tar n'a pas pu créer une archive (sinon, dans un tel cas, vous perdriez tous les messages que vous vouliez archiver !). Bien entendu, seule une des deux structures en if subsistera dans votre script réel, vous devrez choisir l'une ou l'autre selon que vos messages envoyés sont stockés dans un unique fichier (premier if) ou dans des fichiers multiples à l'intérieur d'un répertoire (second if). Le if teste donc la « valeur de retour » de la commande qui vient d'être exécutée (ici tar), valeur de retour qui est toujours placée par le shell dans la variable spéciale du shell : $? ; une valeur de zéro représente le succès de la commande tar, toute valeur différente représenterait un code d'erreur indiquant que l'archive n'a pu être créée correctement. Sur la commande tar, voir la page La commande tar. Dans le premier if le fichier contenant les messages sera vidé de son contenu en redirigeant vers lui la sortie nulle de la commande echo employée sans argument. (Pour le sens de l'indicateur de redirection >, voir Le shell sans peine#Redirection vers un fichier ou en provenance d'un fichier). Pour la commande rm voir Le shell sans peine#Pour nettoyer, l'option -f empêche toute demande de confirmation. Enfin exit 1 interrompt le script (ici, sans rien supprimer) en renvoyant le code d'erreur 1.
Vous voyez bien que ce n'est pas si compliqué que cela !!!
Pour rendre les choses plus concrètes, si vous utilisez le courielleur Thunderbird, vous choisirez la première version de if et un fichier de courrier envoyé aura un chemin du type suivant (si votre nom d'utilisateur est toto) |
Rendez le script exécutable avec chmod +x fichier (sur la commande chmod, voir Permissions#Modifier les propriétés d'accessibilité à l'aide de chmod).
Testez en utilisant un fichier de sauvegarde (c'est toujours une bonne
idée de tester ses scripts avant qu'ils ne causent des dommages).
Ensuite éditez votre crontab avec crontab -e et ajoutez-y ces lignes :
# pour les mois de 31 jours 59 23 31 1-7/2,8-12/2 * sh votre_script_avec_le_chemin_complet # pour les mois de 30 jours 59 23 30 4,6,9,11 * sh votre_script_avec_le_chemin_complet # enfin, pour février. 59 23 28 2 * sh votre_script_avec_le_chemin_complet
Si tout se passe bien, le démon crond appellera votre script la dernière minute de chaque mois. Le script compressera le fichier ou le dossier sent_mail, stockera le résultat sous $HOME/mail/sent_mail~MoisAnnée.tar.gz et videra le fichier ou le répertoire sent_mail.
Mais attention ! vous devez être sûr que votre PC sera allumé la dernière nuit de chaque mois ! Car un job de crontab ne sera PAS exécuté du tout si l'ordinateur est fermé au moment prévu pour son exécution, notez bien qu'à la différence d'un job de at, un job crond ne sera pas lancé au démarrage de l'ordinateur dans ce cas...
Si vous n'en êtes pas sûr, alors, il va falloir penser à utiliser anacron et donc à poursuivre votre lecture jusqu'à la section suivante...
[modifier] Exécution régulière d'une tâche sur un ordinateur souvent éteint : anacron
Si vous regardez le contenu du fichier /etc/crontab, le fichier de configuration du démon crond, vous pourrez observer que, par défaut, les tâches quotidiennes, hebdomadaires ou mensuelles prévues par le système sont exécutées entre 4 et 5 heures du matin. Si votre ordinateur n'est pas allumé à ce moment-là, les « jobs » de cron ne seront tout simplement pas exécutés !!
Une solution possible serait de modifier les champs d'heure en leur donnant une valeur correspondant à un moment de la journée où il est probable que votre ordinateur soit allumé (j'ai, un temps, mis moi-même tout cela à 14h).
Une autre possibilité serait d'avoir recours au service du système anacron.
La première chose à faire dans ce cas est de vous assurer que le service est installé et activé sur votre système :
- soit en vous rendant dans le Centre de Contrôle Mandriva (clic sur l'étoile jaune, puis Système->Configuration->Configurer votre ordinateur, choisir Système puis Activer ou désactiver les services système)
- soit en empruntant le raccourci que constitue la console (en tant que root).
Pour vérifier en console la présence du service anacron faites :
chkconfig --list anacron
si vous obtenez un message d'erreur tel que erreur lors de la lecture d'informations sur le service anacron : Aucun fichier ou répertoire de ce type, installez alors le paquetage pour anacron. Cela fait, lancez le service ainsi :
chkconfig anacron on
Notez bien qu'anacron n'est pas du tout destiné à remplacer cron, il s'y ajoute et coexiste avec lui...
anacron (en anglais anachronistic command scheduler ou
planificateur de commande « anachronique ») utilise des
indications de temps relatives (« une fois par jour / par semaine
/ par mois ») au lieu de références temporelles absolues
(« le 14 janvier 2008 à 15h 30 »). De la sorte, même si vous
« manquez » un moment ou une date particulière où l'exécution
d'un « job » était prévue, celui-ci sera tout de même exécuté
peu de temps après le prochain démarrage du système. Voici comment ce service fonctionne :
- anacron recherche les « fichiers dateurs » (anglais timestamps) correspondant à ses différents jobs dans /var/spool/anacron
- si, d'après un des fichiers dateurs, un job est en attente, anacron le lance
- anacron met à jour le fichier dateur du job en question.
Le fonctionnement d'anacron est contrôlé par le fichier /etc/anacrontab. Si vous l'ouvrez dans un éditeur de texte, ou si, plus simplement, vous inspectez son contenu en tapant en console cat /etc/anacrontab, vous constaterez que les jobs système prédéfinis de Mandriva Linux lancés par la commande run-parts y figurent déjà d'emblée :
1 5 cron.daily run-parts /etc/cron.daily 7 10 cron.weekly run-parts /etc/cron.weekly 30 15 cron.monthly run-parts /etc/cron.monthly
- Le premier champ représente la période en jours : 1 pour une exécution quotidienne, 7 pour une exécution tous les 7 jours (fréquence hebdomadaire) etc.
- Le deuxième champ représente la durée, en minutes, qui doit séparer le lancement d'anacron de l'exécution d'un job . Ainsi, 5 revient à dire « lancez le job prévu 5 minutes après l'activation d'anacron ». Ceci permet d'éviter que tous les jobs de la file ne soient lancés en même temps.
- Le troisième champ contient un identifiant. anacron utilise cet identifiant pour ses fichiers dateurs et ses messages. Dans notre exemple, les identifiants sont donc de la première à la dernière ligne : cron.daily, cron.weekly et cron.monthly
- Le quatrième champ contient la commande à exécuter. Dans notre exemple il s'agit toujours de la commande run-parts suivie de son argument (le chemin du répertoire qui contient les scripts que run-parts va lancer).
[modifier] Les limites d'anacron
anacron ne peut remplacer cron, car, contrairement à cron, il lui est impossible d'exécuter des jobs toutes les minutes ou toutes les heures : l'unité de temps d'anacron est essentiellement la journée...
En outre, il ne possède aucun mécanisme permettant de lancer des jobs sous les identités de différents utilisateurs : anacron lance tous ses jobs sous root.
Il faut bien comprendre qu'anacron dans son emploi prototypique se lance une fois par jour au démarrage du système, exécute ses jobs et s'endort jusqu'au prochain redémarrage. Si vous modifiez l'inventaire des jobs et voulez les faire exécuter par anacron, vous pouvez lancer anacron « à la main » à l'aide de la commande service, il faut alors taper en console :
service anacron start
ou en l'activant dans DrakXservices de MCC (lancer sous root en console drakxservices, ou faire Menu K->Système->Configuration->Configurer votre ordinateur->Système->Activer ou désactiver les services système). Il est également possible d'exécuter les jobs prévus en lançant la commande :
/usr/sbin/anacron -s
tous les jobs planifiés pour ce moment seront alors lancés les uns à la suite des autres sans délai entre la fin d'un job et le début du suivant (autrement dit sans tenir compte du second champ d'anacrontab).
D'un autre côté si, de temps en temps - ou même exceptionnellement ! - vous laissez votre machine allumée toute la nuit sans la faire redémarrer le lendemain, les jobs anacron du lendemain ne seront pas exécutés. Pour éviter cela, vous pouvez faire d'anacron un job cron prévu pour les « petites heures ». Ainsi, quand l'ordinateur restera allumé la nuit, les tâches anacron du lendemain seront en tout état de cause exécutées. Vous pouvez obtenir cela en éditant ainsi une ligne de la crontab de root :
01 1 * * * /usr/sbin/anacron -s
(l'option -s assure que les différents jobs seront exécutés les uns après la fin de l'exécution des autres). Cette ligne assurera l'exécution des jobs d'anacron à 1h 01 du matin, si l'ordinateur est allumé à ce moment-là...
Vous aurez remarqué que nous avons donné l'adresse absolue de la commande anacron (nous n'avons pas mis simplement anacron -s comme on le ferait d'ordinaire en console). C'est nécessaire, à moins de placer le chemin /usr/sbin dans une variable PATH spécialement destinée à crond, au début de la crontab, comme ceci, par exemple :
PATH=/usr/bin:/usr/sbin 01 1 * * * anacron -s
Comme at et batch ainsi que crond, anacron est incapable d'afficher un message à l'écran ou de lancer une application graphique. En revanche, elle envoie par courrier à root le contenu de l'affichage écran des commandes qu'elle exécute, mais pour pouvoir lire ce courrier vous devez bien sûr avoir installé le mail local.
[modifier] Les variables d'anacron
Comme on peut le faire dans les crontab, il est possible aussi d'assigner une valeur à des variables dans le fichier anacrontab.
Nous avons vu plus haut qu'on pouvait ainsi définir un PATH pour les jobs anacron.
Il est aussi possible de choisir un shell via la variable SHELL.
On peut même définir une variable de son choix à utiliser dans un job. Une anacrontab qui contiendrait ceci :
MESSAGE="C'est pour aujourd'hui !!" 30 0 * * * echo "$MESSAGE"
enverrait par mail une fois par mois le message « C'est pour aujourd'hui !! ».
En revanche, assez curieusement, il ne semble pas que contrairement à ce qui vaut pour les crontab, il soit possible de modifier ainsi le répertoire de travail ou le destinataire des mails pour les jobs anacron.
[modifier] La commande run-parts
La commande run-parts a pour effet de lancer tous les scripts contenus dans les répertoires qui lui sont passés en argument.
Elle est utilisée par le système pour l'exécution des tâches périodiques régulières par l'entremise du démon crond.
Ainsi, sous Mandriva, le fichier /etc/crontab pourra se présenter pour l'essentiel ainsi :
01 * * * * root run-parts --report /etc/cron.hourly 02 4 * * * root run-parts --report /etc/cron.daily 22 4 * * 0 root run-parts --report /etc/cron.weekly 42 4 1 * * root run-parts --report /etc/cron.monthly
Ce qui signifie que, lorsque l'ordinateur est allumé :
- toutes les heures, à la première minute, les scripts du répertoire /etc/cron.hourly sont exécutés (par conséquent à 00h 01, 1h 01, 2h 01 etc.)
- tous les jours, à 4h 02, les scripts du répertoire /etc/cron.daily sont exécutés
- tous les dimanches, à 22h 04, les scripts du répertoire /etc/cron.weekly sont exécutés
- tous les 1er du mois, à 4h 42, les scripts du répertoire /etc/cron.monthly sont exécutés.
L'option --report affiche le nom des scripts exécutés qui ont une sortie. Cela rend plus compréhensible le message contenant ces sorties envoyé par le mail local à l'administrateur.
Il est possible de régler la priorité des scripts lancés par rapport aux autres processus en utilisant la commande nice. Par exemple, pour leur donner une priorité faible par rapport aux processus courants on pourrait avoir un /etc/crontab comme ceci :
01 * * * * root nice -n 19 run-parts --report /etc/cron.hourly 02 4 * * * root nice -n 19 run-parts --report /etc/cron.daily 22 4 * * 0 root nice -n 19 run-parts --report /etc/cron.weekly 42 4 1 * * root nice -n 19 run-parts --report /etc/cron.monthly
Sur une machine qui n'est pas allumée en permanence, on aura sans doute avantage à installer anacron. Sous la Mandriva, l'installation d'anacron fera automatiquement du lancement de run-parts une tâche anacron intégrée au fichier /etc/anacrontab. Voir là dessus la section sur anacron.
[modifier] La planification interactive et l'affichage de message : KAlarm
at, cron et anacron ne permettent pas de lancer des programmes qui demandent des informations à l'utilisateur, comme peuvent le faire les applications X. Ceci est dû au fait qu'elles ne possèdent pas de shell d'où lancer un programme. sleep peut faire cela, mais seulement dans le cours d'une seule et même session.
Le programme rclock et l'utilitaire KAlarm de KDE peuvent lancer des programmes interactifs à un moment prédéterminé.
[modifier] Le programme rclock
Le programme rclock appartient au paquetage rxvt. On peut lui demander d'exécuter une commande incluant l'affichage de messages et/ou le lancement d'une application, y compris une application graphique, en éditant un fichier ~/.rclock.
On peut par exemple ajouter la ligne suivante dans ce fichier pour demander l'affichage chaque jour à midi du subtil message indiqué :
12:00 A la bouffe !!
Il est aussi possible de lancer une application...
Par exemple, vous lancerez automatiquement Thunderbird chaque jour à 12 h, en plaçant la ligne suivante dans votre ~/.rclock (je suppose que /usr/local/bin/thunderbird est un lien vers l'exécutable de Thunderbird, pour savoir ce qu'il en est chez vous, utilisez la commande whereis thunderbird) :
12:00 ; /usr/local/bin/thunderbird
Vous pouvez aussi afficher un message qui apparaîtra dans une fenêtre comportant un bouton Start que vous devrez presser pour lancer l'application (cliquer sur le bouton Defer amènera rclock à vous reposer la question plus tard et le bouton Done abandonnera le lancement) :
12:00 Lancement de Thunderbird ? ; /usr/local/bin/thunderbird
Pour plus d'informations sur la syntaxe à utiliser dans le fichier ~/.rclock, lisez man rclock, qui se termine par un exemple détaillé.
Sous KDE, vous pouvez lancer systématiquement rclock au démarrage de la session en créant un lien symbolique vers l'exécutable de rclock (dont vous trouverez le chemin exact par un whereis rclock) dans le répertoire Autostart de KDE :
ln -sv /usr/X11R6/bin/rclock /home/toto/.kde/Autostart/
Sous GNOME, vous obtiendrez le même résultat en passant par Système > Préférences > Avancé -> Session > Programmes au démarrage.
[modifier] L'utilitaire KAlarm de KDE
Cet utilitaire, très facile à configurer en remplissant des champs appropriés, faciles à repérer, dans une fenêtre de configuration bien conçue, permet, lui aussi, d'afficher des messages ou de lancer des applications graphiques à des moments déterminés.
Vous y accèderez via Menu K->Bureautique->Gestion du temps->K Alarm.
KAlarm est doté d'une aide en français, il ne sera donc pas nécessaire que nous nous étendions davantage ici sur cet excellent outil.