The Troll's factory

Geekeries & pensées
-->

Les tâches planifiées sous Linux (cron, crontab) : seconde approche

Bonsoir la compagnie,

Après avoir fait joujou une première fois avec les tâches planifiées sous cron gnu/linux, je vous avais promis de vous en dire plus sur les procédés et les possibilités du système de planification des tâches de GNU/Linux : cron.

Résumé de ce que vous savez déjà faire si vous avez lu la première partie sur les tâches planifiées cron :

  • Créer une tâche planifiée simple qui lance un fichier exécutable avec l’utilisateur courant (celui qui a créé le cron) à l’aide la commande crontab
  • Faire des tâches planifiées à exécution unique (planification non régulière/récurrente)
  • (Utiliser un autre éditeur pour la commande crontab -e)

Ce que je vais vous apprendre en plus dans cet article :

  • Gérer des dates complexes : Répétitions, récurrence des tâches planifiées (jokers, répétitions, sélections multiples)
  • Définition d’un fichier personnalisé de tâches planifiées
  • Définir une tâche exécutée par un utilisateur précis.
  • Éxécuter une tâche planifiée dans un répertoire particulier.
  • Éxécuter une tâche planifiée graphique.
  • Gérer les sorties des commandes exécutées par CRON : logs, mails, etc.

Je vous donnerai également quelques filons pour l’utilisation de PHP avec CRON.


Retour sur la planification des tâches : la syntaxe des dates avancées avec CRON.

Je ne refais pas les explications sur les dates simples dans CRON, c’est le sujet de la première approche (dont vous avez les liens au début de cet article). Nous allons voir comment créer une tâche récurrente, à l’aide des jokers, répétitions et sélections multiples.


Le joker : *

Comme dans beaucoup d’applications informatique, le joker chez Cron est l’étoile « * ». Ainsi, si vous remplacez un quelconque paramètre d’une date par une étoile, cela signifie pour cron « quelque-soit la valeur de ce paramètre ».

Exemple : Quelque-soit le jour, je veux que à 7h05 tu dises bonjour, durant tout le mois de février :

05 07 * 02 * echo 'Hello World !'

Ici nous avons remplacé le numéro du jour dans le mois, ainsi que le jour de la semaine (qui est également susceptible de varier !) par le joker « * », ainsi, quelque-soit les valeurs de ces paramètres, si les autres paramètres (heure, minute, mois) sont vérifiés, CRON dira bonjour au monde.


La répétition : /

Le joker permet de spécifier, au maximum, une répétition toutes les unités de temps d’un paramètre précis. En effet, si je mets un joker pour l’heure, alors cela sera exécuté toutes les une heure, puisque cela sera « quelque-soit l’heure ». Ainsi, avec les jokers, vous pouvez répéter au mieux : tous les jours, toutes les heures, toutes les minutes, tous les lundis, tous les mois… Bref, pas terrible comme flexibilité tout de même. C’est à cela que sert la répétition, elle vous permet de dire tous les combien de variation d’un paramètre vous voulez que cela se répète. Une variation d’un paramètre, c’est +1 minutes, +1 heure, +1 jour, etc. …

L’opérateur de répétition s’utilise comme suit : valeur_param/intervalle_de_repetition

Ainsi, si je veux que toutes les 15 minutes, une action se répète, quelque-soit la date :

*/15 * * * * /usr/bin/monaction

On utilise ici également le joker, puisque l’action se répète quelque-soit la minute, l’heure, ou la date…




Les intervalles et les sélections multiples

Vous pouvez également définir plusieurs valeurs d’un paramètre pour lesquelles la tâche sera exécutée. On procède soit en donnant un intervalle de valeurs, soit une liste de valeurs.

Opérateur d’intervalle : -

Utilisation : borne1-borne2 ou borne1 et borne2 sont les bornes de l’intervalle ( [borne1 ; borne2] ) et incluses.

Exemple : La précédente action se répète toutes les 15 minutes, du 1er au 10 du mois

*/15 * 1-10 * * /usr/bin/monaction

Opérateur de valeurs multiples : ,

Utilisation : valeur1, valeur2, valeur3…

Exemple : La précédente action se répète toutes les 15 minutes mais seulement entre 02h et 03h puis entre 05h et 06h

*/15 2,5 * * * /usr/bin/monaction



Définir une fichier cron personnalisé : Cron en mode admin

Jusqu’à présent, vous avez utilisé la commande crontab afin de modifier votre fichier cron et d’ajouter ou de supprimer des tâches.

En réalité vous n’avez utilisé que le côté « utilisateur » de cron. La suite n’est ouverte qu’à un accès root, autrement dit l’administateur de la machine, car elle permet notamment de décider de sous quel utilisateur vont être exécutées les tâches, ce que nous verrons en même temps.

Si ce mode d’utilisation de cron n’est réservé qu’à l’administateur, c’est pour plusieurs raisons :

  1. Il va permettre, comme je l’ai dit, de choisir l’utilisateur qui exécute la commande
  2. Le répertoire dans lequel nous allons créer le fichier appartient à root
  3. Seul root peut demander à cron de recharger les fichiers de configuration, or nous en aurons besoin car comme nous allons éditer de simples fichiers, la commande crontab ne sera pas là pour, à la fin de l’édition du fichier, dire à cron « Hey hey, ouhou, on a modifié le fichier là, viens y jeter un coup d’oeil » et par défaut cron ne verra donc pas vos modifs sans reload, et donc sans droits d’admin.




Créer votre fichier de tâches planifiées : le répertoire /etc/cron.d/

Vous êtes donc maintenant loggé en root, ou, si vous n’avez pas le su sur votre machine, vous exécuterez le reste des commandes avec un « sudo » devant.

Les fichiers de tâches planifiées sont placés dans le répertoire /etc/cron.d/, qui appartient à root.

Créons-y un fichier :

vim /etc/cron.d/monfichiercron

Voilà, tout le travail est fait… ou presque. Dans ce fichier, vous pouvez placer des tâches planifiées exactement de la même façon qu’avec la commande crontab à la différence prêt… qu’il faut spécifier l’utilisateur d’exécution !

Cela donne :

mm HH JJ MM joursemaine utilisateur /chemin/commande

Exemple, je suis l’utilisateur Troll, je veux que l’utilisateur Toto fasse le ménage dans son dossier personnel chaque semaine (vision geek du Range ta chambre ! maternel/paternel), on dira qu’on est un peu radical, si le dimanche il n’a pas vidé son dossier perso (il est censé le faire le samedi) tant pis : tout poubelle !
Note : A NE PAS TESTER CHEZ VOUS ! Vous risqueriez d’avoir de sérieux ennui ^^

01 00 * * sun toto rm -fR /home/toto/*

Bien sûr l’utilisateur peut aussi être root… But, be careful !

Ensuite, une fois que vous avez sauvegardé votre fichier, il faut dire à cron de le relire pour l’intégrer :

(encore une commande à faire en root, si vous avez bien lu le début de ce paragraphe !)
/etc/init.d/crond reload

Cron a bien rechargé s’il dit ça normalement :

Reloading crond: [ OK ]




Les autres fichiers préconfigurés de cron :

Cron a également des dossiers préconfigurés, dans lesquels il vous suffit de mettre un script (ou un lien symbolique, solution la plus souvent utilisée) exécutable.

Ces dossiers sont les suivants :

  • /etc/crond.daily : exécution quotidienne (chaque jour à 4h02)
  • /etc/crond.hourly : exécution chaque heure (chaque heure + 1 minute)
  • /etc/crond.weekly : exécution hebdomadaire (le dimanche à 4h22)
  • /etc/crond.monthly : exécution mensuelle (le 1er du mois à 4h42)

Comme je suis gentil, je vous donne même les commandes :

Création d’un script exécutable dans un dossier :
(en root encore et toujours)
vim /mon/chemin/de/fichier && chmod +x /mon/chemin/de/fichier

Création d’un lien symbolique dans /etc/crond.daily (par exemple) pointant vers /mon/chemin/de/fichier :

ln -s /mon/chemin/de/fichier /etc/crond.daily/monscript && chmod +x /etc/crond.daily/monscript

L’avantage du lien symbolique c’est que vous pouvez mettre votre script dans un dossier où vous le retrouvez et vous pouvez placer un lien dans plusieurs dossiers /etc/crond.XXX/ sans avoir à modifier tous les fichiers quand vous modifiez le script (principe du lien symbolique).




Éxécuter des tâches planifiées dans un répertoire particlier

Il peut s’avérer que vous ayiez besoin d’exécuter une commande qui va chercher des fichiers ou autres dans son répertoire courant et qui sera donc perdue si vous la lancez avec cron de la manière /chemin/commande

Pour cela, utilisez tout simplement la commande cd :

03 01 * * * tutu cd /home/tutu/scripts/ && ./macommande




Éxécution d’une tâche planifiée graphique

La console, y’a rien de mieux, ça plante pas, ça vous cache rien… Mais c’est pas très esthétique. Puis si vous voulez par exemple lancer Amarok pour vous reveiller en musique, Amarok va avoir besoin d’une interface graphique (sauf si vous connaissez une interface ligne de commande pour amarok, auquel cas je veux bien que vous partagiez l’info avec moi !).

Pour cela, procédez comme suit : placez DISPLAY=:0 après le jour de la semaine, ou après le nom d’utilisateur quand celui-ci est spécifié.

Si vous utilisez une commande composée, du type :

/chemin/premierecommande && /chemin/deuxiemecommande

(ce qui est notamment le cas lorsque vous exécutez dans un répertoire particulier) alors vous devez mettre le DISPLAY=:0 juste avant la commande qui aura besoin de l’affichage.

Gérer les sorties des commandes exécutées par CRON : logs, mails, etc.

Par défaut, notamment lors de la définition d’une tâche planifiée avec crontab -e, si votre commande génère une sortie vous devez – en théorie (désactivé sur certaines distrib’) – recevoir un « mail » ( dans /var/spool/votrelogin ) avec la sortie générée.

Ce n’est pas vraiment un mode très pratique pour logger et retrouver les sorties de vos tâches planifiées préférées.

Je vais donc vous montrer comment enregistrer dans un fichier log la sortie de vos tâches planifiées.

En fait, cela revient au même que pour enregistrer dans un fichier log une commande console standard. Cela revient à faire comme ceci :

Enregistrer tout dans monfichier.log (sortie normale + erreurs)
/chemin/macomandequigenereunesortie > monfichier.log 2>&1

Enregistrer seulement les erreurs dans monfichier.log :

/chemin/macomandequigenereunesortie > /dev/null 2> monfichier.log

Ne rien enregistrer :

/chemin/macomandequigenereunesortie > /dev/null 2>&1

Attention, tel que c’est présenté ici, chaque nouvelle exécution remplace le contenu de monfichier.log

Si vous voulez logger sur plus d’un seul lancement, vous devez créer le fichier monfichier.log avant (ce qui n’était pas nécessaire précédemment) et remplacer systématiquement dans les précédentes commandes, le « > » par « >> » (enfin presque, pas tous, regardez ci-dessous).

Ce qui donne :

/chemin/macomandequigenereunesortie >> monfichier.log 2>&1
/chemin/macomandequigenereunesortie > /dev/null 2>> monfichier.log
/chemin/macomandequigenereunesortie > /dev/null 2>&1


Annexes : Utilisation de PHP avec CRON

Pour lancer une tâche écrite en PHP avec cron, saisissez une tâche de la manière suivante :

mm HH JJ MM joursemaine [user] /usr/bin/php -f /chemin/de/fichier.php

Ou, ce qui est conseillé avec PHP, avec exécution dans un repértoire particulier :

mm HH JJ MM joursemaine [user] cd /chemin/de/ && /usr/bin/php -f ./fichier.php

Bien évidemment, vous pouvez logger dans un .log avec les .php comme avec n’importe quelle autre commande.

Voilà, c’est terminé : des remarques, des erreurs à signaler, des questions -> Les commentaires sont là pour ça ! J’espère avoir été clair et que cet article sera utile au plus grand nombre :-)

Share and Enjoy:
  • Print
  • PDF
  • Twitter
  • Facebook
  • LinkedIn
  • RSS
  • Wikio FR
  • Digg
  • del.icio.us
  • Google Bookmarks
  • Technorati
  • Sphinn
  • Mixx
  • Add to favorites
  • Live
  • Netvibes
  • Scoopeo
  • viadeo FR
  • Identi.ca
  • MySpace
  • StumbleUpon
  • Yahoo! Buzz
posté par Troll dans Administration serveur,Scripts, astuces, dév. web avec 22 commentaires

22 réponses à “Les tâches planifiées sous Linux (cron, crontab) : seconde approche”

  1. gaelle dit :

    Bonjour,
    deja super tuto je ne connaissais rien au tache planifié et la c’est tout clair merci beaucoup!
    alors je ne sais pas si c’est ici qu’on peut poser des questions je tente quand meme…

    j’ai juste une question à poser du moins je voudrais une precision :

    voila je souhaiterai faire une tache simplifié pour supprimer des fichiers dans les dossiers ftp de chaque personne de l’entreprise ou je travail tout les 21jours à partir de la date de depot du fichiers

    en gros :
    je suis l’utilisateur toto
    et dans mon fichier /home/ftp/toto j’ai plus de 120 fichiers
    (si les 300personnes de l’entreprise ont se nombre de fichiers risque de saturation du DD)

    mon 1er fichier a été deposé le 3mai a 8h59
    le 2eme le 3mai a 11h
    le 120eme le 5mai a 14h

    je souhaiterai qu’au bout de Xjours (que je determinerai avec mon responsable) tout les fichiers contenu dans /home/ftp/toto/* soit tous supprimer

    evidement cette tache doit se faire pour mon dossier mais pour les 300 personne de la société qui auront tous un dossier du type /home/ftp/nom_user/leur fichier

    j’ai vu qu’on pouvait utilisé la répetion mais est ce qu’elle s’applique au dossier aussi?
    et comment calculer l’ecart entre les deux dates?

    si vous pouviez m’aider
    Merci d’avance
    une stagiaire qui doit faire une tache planifié

  2. Troll dit :

    Salut Gaelle.

    Tout d’abord, merci du compliment, content que ça serve :)

    Ensuite la question que je me pose est : ton problème est-il tant au niveau de la planification plutôt qu’au niveau de la suppression ?

    En fait il faut bien faire la différence : cron sert à planifier, à lancer.

    Cron n’agit pas en lui-même.

    Si tu es dans un environnement GNU/Linux, il faut que tu fasses un script dans le langage de ton choix (Shell, PHP, Perl, Python…) qui aura pour mission d’aller supprimer tous els fichiers dans ce répertoire.

    Ensuite tu planifies dans cron le lancement de ce script tous les 21 jours grâce en effet à la fonction de répétition.

    Voilà :)

    Si tu as d’autres questions / précisions à demander sur cron, n’hésites pas à reposter un commentaire.

    Si tu veux de l’aide pour faire ton script qui supprimera les fichiers, et que ça ne concerne plus cron, alors on va éviter de faire ça dans les commentaires de ce billet et dans ce cas je te conseille de te rendre à cette adresse : section OS Libres sur PCInfo-Web.

    J’y suis notamment actif et je pourrai t’y donner un coup de main pour le script. Si tu ouvres un sujet sur ce forum tu peux me le dire (=donner l’url de ton sujet) dans les commentaires (ici) afin que je ne le loupe pas :) .

    Voilà, bonne journée à toi :)

  3. […] = '_Troll';Mise à jour : La deuxième partie de ce guide sur les tâches planifiées, intitulée Tâches planifiées sous Linux (cron, crontab) : Seconde approche est dorénavant disponible ici : Tâches planifiées sous Linux (cron, crontab) : […]

  4. […] = '_Troll';Mise à jour : La deuxième partie de ce guide sur les tâches planifiées, intitulée Tâches planifiées sous Linux (cron, crontab) : Seconde approche est dorénavant disponible ici : Tâches planifiées sous Linux (cron, crontab) : […]

  5. pakalou dit :

    Bonsoir,
    j’ ai apris des choses que je ne connaissais pas.
    Pour autant deux questions me taraude…

    Comment faire pour ciblé que le deuxieme mardi de chaque mois ?
    Dois je me dire qu c’est entre le 7eme et 14 eme jours ou ya t il une solution plus judicieuse ?

    Si deux utilisateurs lancent chacun leur crontab (toto et root par exemple) et que c’est les même parametre à l’identique : lesquel sea prioritaire ?
    D’avance, merci pour la réponse

    Pakalou

  6. Troll dit :

    Effectivement je n’aurais pas d’autre idée à part ce que tu as cité pour le second mardi du mois. Sinon pour l’ordre d’exécution des crontab il faudrait chercher ds la doc mais j’aurais tendance a dire en simultané en lançant plusieurs processus soit root en prioritaire.

  7. babarbapapa dit :

    Pour les fichiers vieux de plus de 21 jours, boucler sur la liste des utilisateurs, et utiliser la commande find -ctime 21 pour déterminer une liste des vieux fichiers. Ensuite, rm -f (ou gzip si tu es plus tolérant).

    Pour le premier mardi du moi, c’est forcément le mardi entre le 8eme et le 14eme jour (le 7eme peut être le premier mardi si on commence un mercredi)

    L’utilisateur est précisément un paramètre de crontab, donc toto et root ne peuvent pas avoir des crontab avec les même parametres.

  8. 100 giga dit :

    bonjour j’ai un système sous linux (qui gère un répertoire téléphonique) que je doit redemarer chaque matin manuellement. je voudrai que tu m’aide a verifier que ce n’est pas une tache planifiée dans le crontab qui cause ceci et aussi comment creer un fichier cron pour redemarer automatiquement chaque matin ! merci d’avance

  9. Troll dit :

    Salut « 100 giga »,

    La question que tu as est un peu éloignée du but initial de cet article et demande un espace fait pour aider pour ça, je te propose de poser ta question ici : Forums d’Entraide PCInfo-Web.

    J’y suis actif, je répondrai à ta question ;)

  10. Bong armand dit :

    Votre cours est très enrichissant. cependant j’ai besoin de votre aide.
    Que veut dire &amp?

    De plus j’ai écrit un script en perl que je voudrais exécuter automatiquement.mon script s’appelle log_radius et et se trouve dans le fichier /var/log/.

    voila ce que j’ai écrit dans mon crontab

    */2 * * * * root cd /var/log && ./log_radius

    mais je n’ai pas de résultat;

    j’ai besoin de votre aide

  11. Troll dit :

    Salut Armand,

     » && » signifie « Arf, le html est mal passé ».

    En clair « & » = « & » sauf que des fois les éditeurs de WordPress font un peu de la m*** et mettent & (le caractère HTML pour « & »).

    Sinon, quand tu dis que tu « n’as pas de résultat » tu veux dire quoi ? N’oublie pas que c’est exécuté « hors shell » en quelques sortes. Si tu veux la sortie de ton script, il faut la rediriger vers un fichier :

    ./log_radius > versmonfichier.log

    Sinon, ça enregistre dans la « inbox » de mémoire, que tu peux consulter sur ton disque dur… je ne sais plus trop où (faut chercher un peu sur le net « inbox linux user » tu devrais trouver).

  12. Federer 2013 dit :

    Merci pour ce tuto très enrichissant …

    Je cherche à exploiter cron pour pouvoir envoyer les rapports de scan de ClamAV par mail.

    J’espère que vous pourriez m’aider.

    ma conception est la suivante:

    planifier une tache quotidienne qui scanne la totalité des dossiers/fichiers (à 22heure par ex). ==> Génération d’un fichier résultat..

    planifier après une tache qui envoie un mail avec comme Pièce Jointe le fichier scan… quelle solution d’envoi de mail est la plus adéquate ? postfix?

    Merci de votre aide..

  13. Troll dit :

    Salut Federer 2013,

    Ta question demande une réponse un peu plus détaillée et sort de l’application directe de l’article. Du coup, pour une aide un peu plus générale sur l’informatique, je te conseille de poser la question ici : PCInfo

    J’y suis notamment assez actif et je pourrai répondre sur ton sujet une fois celui-ci créé (section « OS Libres » :) ).

  14. Federer 2013 dit :

    T’es pas un Troll, tu es un ange :) !

    J’ai posté la question sur PCInfo..

    Merci

  15. AZZ dit :

    Bonjour Troll pour ce tuto enrichissant

    en fait moi je veux lancer un script par exemple à un intervalle donné par l’utilisateur c-à-d, l’utilisateur doit spécifier l’intervalle en argument [passé en paramètre les valeurs au script ] et ensuite planifier les taches en fonction de ces valeurs

    par exemple :

    mm HH JJ MM joursemaine ./script.sh mm HH

  16. Troll dit :

    Salut AZZ,

    Alors ça dépend ce que tu entends par « spécifiés par l’utilisateur ».

    Le but d’une tâche planifiée c’est d’être autonome. Donc au moment où la tâche s’exécute, on demande rien à l’utilisateur, puisqu’il n’est peut-être même pas devant son ordinateur (enfin, on peut le faire, avec une interface graphique, notamment, mais c’est pas terrible).

    Par contre, tu peux très bien passer des paramètres à ton script dans le crontab.

    Exactement de la manière dont tu l’as écrit d’ailleurs :

    mm HH JJ MM joursemaine /chemin/vers/ton/script.sh param1 param2

    Voilà. Après, comment récupérer les paramètres dans un script, c’est hors de la portée de ce tuto, mais en bash c’est $0 $1 $2 etc. … ($0 c’est le nom du script, comme en C, Python, C++, Ruby, etc. …).

  17. Fredy dit :

    Juste pour te dire que ton tuto est génial.
    C’est la 10 ou 15e que je lis et ici tout est clair.

  18. Troll dit :

    @Fredy: Merci :)

  19. Foretriks dit :

    Article très instructif, mais j’ai un petit souci (pour info, je suis sous Mint 17.1).

    Lorsque je tape
    /etc/init.d/crond reload

    il me répond ceci
    sudo: /etc/init.d/crond: command not found

    J’ai essayé d’autres manips basiques : redémarrer (sic), cron restart et autres

    Alors, kefè-je ? :-)

  20. Alexis dit :

    Bravo pour le tutu ! clair et exhaustif après avoir lu des explications éparpillées et incomplètes, ça met bien les idées au clair

  21. Troll dit :

    Salut Foretriks,

    L’article est maintenant assez vieux et les distributions Linux ont déprécié l’utilisation des scripts situés dans /etc/init.d/ (quand ça marche, on le change, bienvenue sous Linux).

    Tu peux essayer la syntaxe suivante :

    sudo service cron reload

  22. Cronpanpa dit :

    Hello,

    J’ai un problème sous Cron : j’ai planifié une tache avec une commande un peu longue (en root) :
    @reboot /usr/sbin/sed -i « s/blablabla/blablablu/g » fichier_à_modifier
    mais rien ne se passe, et quand je vais voir ce qui s’est passé avec #systemctl status cronie (je suis sous Arch), il me dit « Prematured EOF », en me montrant ma commande… tronquée (genre /usr/sbin/sed -i « s/blabl).
    Je crois donc comprendre qu’il n’accepte pas les commandes trop longues, mais comment contourner ce problème ?

Poster un commentaire

Remplissez le formulaire suivant pour poster un message.
Nom
Email
Site internet
Votre commentaire