synCRONisme: une dissertation subjective sur les limitations de CRON

Gazette Linux n°185 — avril 2011

Gaël Montreuil

Adaptation française  

Prénom Nom du relecteur

Relecture de la version française  

Article paru dans le n°185 de la Gazette Linux d'avril 2011.

Cet article est publié selon les termes de la 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

The Trouble with Cron
les vrais Sysadmins
Les autres programmes cron
raffinement
Une solution suffisante
Autres problèmes de cron
Fonctions souhaitées
Résumé
À propos de l'auteur
 

La folie est héréditaire - elle nous est transmise pas nos enfants

 
 -- Sam Levenson

Mon fils cadet (Rob, bientôt 22 ans) veux plus d'Internet. C'est évident. 20 Gio par mois ne lui suffisent pas. Le temps de son absence, nous luttions avec ma femme pour atteindre 20% de ce total.

Au fil des ans, j'ai developpé des dizaines de mécanismes pour superviser notre consommation internet. Bon en fait, peut être 5. Ou bien un seul, que j'ai amélioré 4 fois. Et qu'est ce que j'apelle notre consommation internet? Pas notre consommation; Pas la mienne, pas celle de ma femme; nous sommes raisonnables. Uniquement celle de Rob. S'il ne s'agissait pas de lui, je n'aurais rien besoin de monitorer du tout.

Bon, si je supervise une quelquonque consommation d'Internet, autant que je supervise tout le monde.

Il vient de rentrer de 5 mois d'études en Malaisie. Il m'apporte une offre de fournisseur d'accès qui propose 100 Gio par mois (avec une « clause-trappe » ou deux). Puisque le sujet est sur la table, je vais vérifier notre consommation Internet pour ce mois-ci.

Tous ceux qui me connaissent savent que je me sens plus à l'aise dans un xterm. Je pourrais lancer Firefox et visiter une demi-douzaine de pages pour obtenir mon information, mais il y a longtemps, j'ai développé un script expect, get_optus_usage.exp, enveloppé dans un script shell, get_optus_usage.sh, pour faire le travail à ma place.

j'obtiens quelque chose comme :

   Limite de l'offre = 20000MO
   Données consommées 17% (3517 MO)
   Jours écoulés 7% (2 jours)

Suis-je surpris ? Non. Ennuyé ? Bien—sûr ; mais surpris — jamais.

Je décide qu'il est temps d'executer get_optus_usage.sh plus souvent. Je vais l'éxecuter à 23:55 toutes les nuits. Pourquoi cet horaire particulièrement? Eh bien, la plupart du temps, cela ne fera aucune différence. Tant qu'il est executé toutes les 24h (plus ou moins) J'aurai une idée de notre consommation journalière. Mais le dernier jour du mois, j'aurai une idée de notre consommation mensuelle. Peu après, mon FAI remettra ses compteurs à 0.

Voilà mon problème. Je sais que mon script fonctionne. Je viens de l'éxecuter. (Je sais aussi qu'il ne fonctionne pas toujours. Chaque fois que mon FAI se pique de, disons, créativité, et commence à ré-arranger les meubles, le script plante. Par la suite je le bricole, et il fonctionne à nouveau. Mais ceci n'est pas mon problème du jour (NdT: en français dans le texte original) Est-ce qu'il va fonctionner lorsqu'invoqué à partir de cron ?

Ma réponse spontanée est: pas d'une façon exploitable. Lorsqu'il est exécuté de façon interactive, sa sortie est dirigéé vers xterm (stdout). S'il est exécuté depuis cron, Cette sortie me sera envoyée par message électronique. (En fait elle ne le sera pas : je n'ai pas de démon de messagerie. En tous les cas, une tentative sera faite de me l'envoyer.) Je ne veux pas de sortie dans un message électronique; je la veux dans un fichier journal.

D'accord, alors il faut que je redirige stdout. Je peux le faire depuis l'entrée crontab, quelque chose comme:

55 23 * * * get_optus_usage.sh >> /var/CableUsage/optus_usage.log

(Le fichier /var/CableUsage existe déja en raison de tout le monitorage que j'ai déja effectué — voir plus haut.)

Mais, au bout de tant d'années d'écriture de tâches cron, j'ai appris que cela n'était pas si simple. Les tâches qui fonctionnent correctement durant le développement deviennent plutôt récalcitrantes lorsqu'apellées depuis cron.

Je suis sûr de n'être pas le seul avec ce problème. Je vais jeter un œuil sur Internet. Qu'est ce que je cherche? « cron », bien sûr. Peut être « test »

Je ne suis pas seul! « environ 1.450.000 résultats », me dis Google. Mais attendez. Ce ne sont pas des solutions. Ce sont d'innombrables types aussi perdus que moi qui cherchent des solutions.

Comment tester mon fichier crontab?
Comment tester un nouveau script cron?
Crontab fonctionne-t-il? Comment tester mon script crontab
Comment tester une fonction de cron?

J'ai passé un certain temps à lire les questions et les réponses. La meilleure solution que les gens ont trouvé est de programmer une entrée crontab pour qu'elle s'execute toutes les minutes (ou toutes les x minutes; mais l'idée est qu'il faut un grand nombre de répétitions), puis de corriger le script, attendre la prochaîne minute, vérifier la sortie, etc.

Cette approche est juste tellement mauvaise...

Alors j'ai abandonné. J'ai écrit un script enveloppeur cron_get_optus_usage.sh:

#! /bin/sh
#       cron_get_optus_usage.sh - intermédiaire pour l'appel par cron

        dir=/home/henryg/projects/TECH/web_capture
        $dir/get_optus_usage.sh >> /var/CableUsage/optus_usage.log

Il n'a pas fonctionnée

'...  Le type de votre terminal est inconnu!....  Entrez un type de terminal: [vt100] '

J'ai ajouté

        TERM=xterm
        export TERM

Et ça a marché. Je suis chanceux. Ca n'a pris que deux jours.

 

synchronisme

Etat de ce qui est synchrone; fait de se produire en même temps.

 
 -- Le petit Larousse© Editions Larousse 2007.

Le lendemain, je reçois un e-mail de mon autre fils, Mark.

J'ai un script qui fonctionne bien lorsqu'il est apellé depuis le shell, mais qui ne fonctionne pas correctement lorsqu'il est apellé depuis cron.

Ma réponse contenait tout le savoir que j'avais accumulé au cours de nombreuses années d'utilisation de cron; and cela l'a aidé à résoudre son problème.

Mais, clairement, la demande est là.

The Trouble with Cron

Le principal problème de cron est qu'il est un composant de la production. Même si vous utiliser votre fichier cron personnel, la journalisatiion est toujours redirigés vers le journal système, syslog; les entrées vont dans des fichiers journaux dans /var/log ou similaires; et la communication avec l'utilisateur se fait généralement par le système de messagerie officiel. Il faut donc procéder avec précaution.

Si vous êtes comme moi, vous n'appreciez par que votre journal système soit encrassé. A un moment donné, cela peut interferer avec le disgnostic de vrais problèmes.

Alors vous pensez trouver un mécanisme de test adapté. Vous rêvez!

Avec le programme par défaut cron, le degré de liberté est: s'éxecuter au premier plan, utiliser un programme de messagerie autre que celui par défaut, et deux ou trois autres options qui ne sont pas utiles pour les tests.

Vous ne pouvez pas par exemple utiliser un fichier cron différent de celui par défaut. Alors si vous ajoutez des entrées et que vous êtes distrait par quelque chose, il se peut que crontab se retrouve dans un état instable.

Vous pourriez essayer de tester avec un utilisateur autre que root et affecter uniquement le fichier cron d'un utilisateur. Mais, si votre tâche doit s'effectuer en tant que root (ou autre utilisateur privilégié), cela va engendrer d'autres problèmes.

Il y a deux prérequis pour les tests: la possibilité d'exécuter la tâche maintenant (c.à.d. à la demande); la possibilité de l'exécuter dans un environnement de test identique à l'environnement lorsqu'exécuté depuis cron

les vrais Sysadmins

Soyons clair: je déteste toute notion macho affirmant que les « vrais sysadmins » (NdT: administrateurs système) n'ont pas besoin de ces tests à la noix. On le fait du premier coup. Qu'est ce qui ne va pas chez toi? Tu es une femelette?

Mon credo est de minimiser le risque

Je n'oblige personne à faire des tests. Si vous ne voulez pas en faire, n'en faites pas. J'éspère que vous etes particulièrement brillant ou particulièrement chanceux, parce qu'à mon avis, vous prenez des risques inutiles.

Les autres programmes cron

J'ai fait des recherches sur quelques autres programmes cron.

Anacron(8) semblait prometteur car il est possible d'utiliser l'option -t pour spécifier un anacrontab alternatif. Il y a également l'option -f pour forcer l'exécution de toutes les tâches dans l'anacrontab. Il y a également l'option -n pour executer les tâches maintenant. Non, moi non plus je ne comprend pas la différence entre l'option -f et l'option -n; je les utilise toutes les deux. Vous pouvez l'éxecuter au premier plan, et avoir la joie de voir les messages « d'information vers la sortie standard ». Mais c'est « en plus de vers syslog ».

Tout cela est pas mal. Malheuresement anacron reproduit l'environnement de l'utilisateur interactif.

J'ai également testé fcron (http://fcron.free.fr/). Il ne s'est pas révélé plus utile qu' anacron.

Pour leur rendre justice anacron et fcron ne prétendent pas être destinés à des tests. Pour autant que je sache, il font ce pour quoi ils ont été créés. Il ne m'ont juste pas été utiles.

Il n'y a aucune aide à attendre pour tester les tâches cron.

raffinement

J'ai raffiné mon script. Maintenant il ressemble à:

        dir=/home/henryg/projects/TECH/web_capture
        {
                cat <<EOF
------------------------------------------------------------------------
EOF
                date
                $dir/get_optus_usage.sh
        } >> /var/CableUsage/optus_usage.log 2>&1

Il dessine une ligne pour séparer les entrées, affiche la date et l'heure et exécute le véritable programme (get_optus_usage.sh); et il redirige toute la sortie sur le fichier journal.

Et voici une entrée de journal:

------------------------------------------------------------------------
Wed Feb 23 23:55:01 EST 2011
pèriode de facturation:           01 Feb 11 - 28 Feb 11
Dernière MAJ:           23 Feb 11 11:45 PM AET/AEDT
   Limite de l'offre = 20000MO
   Données consommées 65% (13142 MO)
   Jours écoulés 79% (22 jours)

Tout cela est trés satisfaisant pour cette tâche particulière; mais qu'en est-il de la possibilité de tester cron?

Une solution suffisante

J'ai en quelque sorte une solution. En fait, il est possible de l'invoquer depuis cron. Cela serait probablement ce que je ferais en dernier lieu avant de déclarer qu'une tâche est prête pour la production.

Mais je suis raisonnablement sûr que cette dernière étape n'est pas nécessaire.

Voici le script; je l'ai nommé cronsim.sh:

#! /bin/sh
#       cronsim.sh - simule l'invocation d'une tâche par cron

#----------------------------------------------------------------------#
# Pour personnaliser, modifier
#
#       CRONHOME
#       LOGDIR          (si nécessaire)
#
# par exemple
#
#       CRONHOME=/usr/local/cronsim
#----------------------------------------------------------------------#

        CRONHOME=/home/henryg/projects/TECH/cronsim

        if [ $# -eq 0 ]
        then
                TGT=$CRONHOME/TEST
        else
                TGT=$1
                if [ ! -e $TGT ]
                then
                        cat <<EOF
Specified target script ($TGT) not found.
EOF
                        exit 1
                fi
        fi

        TODAY=`date '+%Y%b%d'`
        LOGDIR=$CRONHOME/logs
        [ -d $LOGDIR ] || mkdir $LOGDIR || {
                cat <<EOF
Unable to create log directory $LOGDIR
EOF
                exit 1
        }
        LOG=$LOGDIR/log.$TODAY

        {
                cat <<EOF
------------------------------------------------------------------------
EOF
                date
                echo 'Calling args <<<'"$@"'>>>'
                ls -la $TGT
                [ -e $TGT ] && env -i $TGT

                cat <<EOF
------------------------------------------------------------------------
EOF
        } >> $LOG 2>&1

Ce n'est pas sorcier.

Habituellement, pour l'invoquer, vous lui fournissez le chemin d'accès vers votre script cron, par exemple:

cronsim.sh get_optus_usage.sh

Si cronsim.sh ne peut trouver le script pour tests, vous obtiendrez un message d'erreur.

En résumé, il invoque le script demandé, journalise toutes les sorties vers un fichier journal daté, enregistre ses arguments d'entrée, et fait un peu d'enjolivage.

Le fragment-clé est

	env -i $TGT

ENV(1)                           User Commands                          ENV(1)

       env - exécute un programme dans un environnement modifié

       -i, --ignore-environment
              démarrer avec un environnement vide.

Exécuter votre script cron avec un environnement vide est éxagéré. Il y a probablement quelques variables d'environnement qui sont définies quand une tâche cron est appelée. Mais cela est suffisant: si votre tâche cron fonctionne (ou peut être modifiée pour fonctionner) sous cronsim.sh, je suis a peu près sûr qu'elle fonctionnera quelque soient les conditions d'invocation.

Vous pouvez démarrer avec un script (ou même avec une partie d'un script) et vous satisfaire de ce qu'il fait lorsqu'invoqué de façon interactive (i.e. comme un script normal) — même sans être administrateur, si cela convient. Si nécessaire, vous pouvez ensuite l'invoquer depuis cronsim.sh, toujours sans les privilèges root pour vous assurer qu'il continue à fonctionner ou pour comprendre quel genre d'ajustements seront nécessaires.

Il est presque certain que vous aurez à définir votre variable PATH.

Je suppose que lorsque vous approcherez d'une version finale de votre script, il se pourrait qu'il soit utile de l'invoquer en tant que root. Vous pourrez toujours l'invoquer par le biais de cronsim.sh (A condition d'invoquer cronsim.sh avec les bons privilèges).

Cela signifie-t-il que lorsque vous l'installerez, votre script sera parfait? Bien sûr que non. Mais je pense qu'il s'approchera bien plus d'une version finale que si vous l'installer dans cron sans tester.

Autres problèmes de cron

Suite à ma recherche internet, je me suis rendu compte que les gens avaient d'autre problèmes avec cron. Il apparaît qu'ils n'arrivent pas à appeler leur script lorsqu'ils le veulent. Je n'ai jamais eu ce problème. On a dit de la syntaxe de cron qu'elle était difficile. Je suppose que c'est en partie vrai.

J'ai eu une difficulté en supervisant notre consommation Internet. J'y ai fait référence précedemment. Auparavant je voulais executer le dernier jour du mois. Cela n'est pas possible avec cron. J'ai dut me contenter de:

55 23 28-31 * * get_optus_usage.sh

Si je me rapelle bien, j'ai par le passé programmé des scripts qui s'attendaient à être invoqué de la sorte, mais qui effectuaient avant tout un calcul pour savoir si le jour actuel était le dernier du mois. Si non, on quitte; autrement, on continue.

Il se peut qu'il y ai une vraie necessité d'un meilleur cron avec un meilleur moyen de spécifier quand les tâches doivent être apellées, mais cela dépasse le cadre de cet article

Fonctions souhaitées

Quelles éléments d'une variante de cron rendrait le test plus pratique?

J'aimerai voir les fonctions suivantes :

  • choisir un fichier cron alternatif

  • appeler une tâche à la demande

  • suspendre l'utilisation du journal système

  • suspendre l'envoie de courriers électroniques

  • exécuter un script comme lorsqu'il est appelé normalement

  • choisir l'utilisateur sous lequel se fait l'exécution

Résumé

Je ne peux pas vous vanter cronsim.sh comme étant testé et à toute épreuve (pas encore). Mais j'y ai eu recours quelques fois, pas tant parce que j'en avais besoin mais pour le roder un peu.

Je suis certain que je vais l'améliorer.

Il se peut qu'au final je déclare la cause comme perdue et que je retourne plancher sur une autre solution. Cela pourrait vouloir dire modifier cron Pour qu'il se comporte comme je veux.

J'aime bien mon script car avecle peu de test que j'ai fait, je me suis rendu compte qu'il était indépendant de la plate-forme. Je l'ai exécuté sous Linux et FreeBSD. Si je commence à modifier cron, cela veut dire du C et de la compilation — et une exécutable différent pour chaque plate-forme.

Je suis curieux de savoir si le groupe cible se réduit à une personne (moi) ou s'il y aurait plus de clients

Et bien-sûr, je suis ouvert à toute suggestion. En particulier, si sur les terres sauvages d'Internet, il existe une variante de cron que j'ai ratée et à laquelle je devrais jeter un œuil, une variante qui remplit les critères mentionnés plus haut, je serai content de l'apprendre.

À propos de l'auteur

Henry Grebler

Henry a passé ses journées à travailler sur ordinateurs, le plus souvent pour des fabricants d'ordinateurs ou des développeurs de logiciels. Ses premières expériences sur ordinateur incluent des reliques comme des cartes perforées, des bandes de papier et des bandes magnétiques. Son secret le plus sombre est d'avoir été payé pour faire des choses alors qu'il aurait payé ppour ça. N'en parlez pas à ses patrons.

Il utilise Linux sur son ordinateur personnel depuis que la famille a reçu son premier PC en 1996. En ce temps là, quand la famille partageait le PC, il était configuré en dual boot Windows/Slackware. Maintenant que chaque membre de la famille possède son propre PC, Henry survit dans un monde purement Linux.

Il habite dans les faubourgs de Melbourne en Australie.

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://www.traduc.org/Gazette_Linux.

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