Crontab : planification des tâches

Fonctionnement et syntaxe

  • Le service crond
    • Il est chargé de faire exécuter par le système toutes tâches (commandes et scripts) définies et planifiées à l'avance (cron vient de chronos, le dieu du temps !)
    • Ces tâches allant de la simple commande aux scripts complexes peuvent ainsi être exécutées à heure fixe et même de façon périodique, et fait l'objet de messages de compte-rendu.
    • La commande /usr/bin/crontab permet cette programmation. Son usage est en principe réservée à root. On peut toutefois autoriser certains utilisateurs. Pour cela on en dresse la liste sur des lignes successives dans le fichier /etc/crond.allow , et de façon symétrique, on peut mettre dans /etc/crond.deny la liste des utilisateurs non autorisés.
      Exemple : seuls jean et toto ont la permission d'utiliser le service crontab
        # ll cron.allow
      jean
      toto

  • Fonctionnement
    • Le processus crond est normalement lancé au démarrage.
      On peut le lancer ou l'arrêter avec /etc/rc.d/init.d/crond
    • Il lit toutes les minutes les fichiers présents dans le répertoire /var/spool/cron (et aussi le fichier /etc/crontab, pour voir si des tâches doivent être exécutées.
    • Chaque action de crond ajoute une ligne de message dans le fichier /var/log/cron, qu'il faut purger de temps en temps ... par une commande crontab !
    • Par défaut si une commande produit un affichage, il est dirigé vers la messagerie

  • Commande crontab [-u user] {-l | -r | -e }
  • Options :
    • crontab -l affiche le fichier crontab de l'utilisateur
    • crontab -r efface ce fichier
    • crontab -l -u jean root examine le fichier crontab de l'user jean
    • crontab -e crée ou édite (pour modification) un fichier temporaire dans /tmp ouvert dans vi
      Lors de la sauvegarde, le fichier est écrit dans /var/spool/cron/$USER, où $USER est le nom de login de l'utilisateur.

  • Syntaxe des lignes des tables crontab
  • Chaque ligne du fichier contient 6 champs, les 5 premières déterminent les moments d'exécution de la tâche décrite au 6ème champ.
    • les 5 premiers, séparés par des espaces, appelés champs temporels, décrivent la périodicité :
      minutes (0-59), heures (0-23), jour du mois (1-31), mois de l'année (1-12), jour de la semaine (0-6, 0= dimanche)
    • le 6ème est la commande à exécuter, ce peut être naturellement un script qcq
    • un champ temporel peut contenir :
      • une valeur précise et valide pour le champ (par exemple 15 sur le champ minute)
      • une liste de valeurs valides, séparées par des virgules (1,3,5 dans le champ mois : janvier, mars, mai)
      • un intervalle valide (1-5 dans le champ jour : du lundi au vendredi)
      • * pour signifier toutes les valeurs possibles du champ (* dans le champ minute : toutes les minutes)
      • */5 (dans le champ minutes : tous les 5 minutes), 0-23/3 (dans le champ heures : toutes les 3 heures)

  • Exemples
  • # exécution chaque 1er et 15 de chaque mois à minuit 
    0 0 1,15 * * commande
    # exécution toutes les heures passées 15 minutes
    15 * * * * commande
    # exécution tous les matins du lundi au vendredi à 7 h 30
    30 7 * * 1-5 commande
    # exécution tous les quarts d'heure de 15 à 19h du lundi au vendredi
    # seulement en 1ère quinzaine du troisième trimestre

    0,15,30,45 15-19 1-15 7-9 1-5 commande
    # trouver puis nettoyer le répertoire /tmp des vieux fichiers (non modifiés
    # depuis 31 jours) tous les 1er jour de chaque mois, à 2 heures du matin

    0 2 1 * * find /tmp -atime 31 -exec rm -f {} \;
    envoyer les messages "Je suis encore au travail !" tous les quarts
    d'heure à partir de 17 h à tous les utilisateurs actuellement connectés,
    et le message "Bonjour chef !" à root tous les jours ouvrables à 10 h

    0 10 * * 1-5 write root %Bonjour chef !
    */15 17-20 * * 1-5 wall %Je suis encore au travail !

TP

Exercices immédiats
  1. Le processus crond est-il actif ? (ntsysv ou ps aux|grep cron)
  2. Envoyer toutes les minutes un petit bonjour à l'utilisateur connecté
  3. L'utilisateur toto ajoute toutes les 5 minutes un message "Bonjour" suivi de la date, dans le fichier /tmp/bonjour.txt
  4. root fait enregistrer de 9h à 17h, les jours ouvrables :
    • toutes les heures, dans /var/log/processus.txt, tous les processus qui tournent sur la machine
    • tous les 5 minutes, dans /var/log/qui.txt, tous les utilisateurs connectés
N'oubliez pas d'arreter ces taches après les avoir testées.

Sauvegarde quotidienne des répertoires personnels

  1. Il s'agit d'effectuer une tâche quotidienne de sauvegarde globale des répertoires personnels présents dans /home dans un répertoire var/sauve/ à créer
  2. Ecrire la commande d'archivage compressé de /home/* dans un fichier home.tgz à placer dans /var/sauve
  3. La sauvegarde doit être quotidienne. A l'aide de la commande date, écrire un script permettent l'archivage du 12 nov dans un fichier nommé home.12nov.tgz
  4. Automatiser cette tâche avec cron, à ... 1h du matin

Autres exos (Ph Chadefaux)

  1. Créer une crontab qui puisse vérifier toutes les deux minutes si samba s'exécute sur le serveur, sinon il faut le relancer, et envoyer un message pour avertir l'administrateur.
  2. Créer une crontab qui surveille si la ligne adsl est toujours montée, si non la remonte.


Annexes

  • L'exécution des taches programmées par cron suppose que la machine soit allumée en permanence. On peut utiliser un autre service, anacron qui se charge de vérifier les taches ainsi non exécutées et va les exécuter dès la remise en route de la machine
  • Comprendre le fonctionnement des commandes placées dans les répertoires temporels
    Fichier /etc/crontab
    # run-parts
    01 * * * * root run-parts /etc/cron.hourly
    02 4 * * * root run-parts /etc/cron.daily
    22 4 * * 0 root run-parts /etc/cron.weekly
    42 4 1 * * root run-parts /etc/cron.monthly
    Fichier /usr/bin/run-parts
    #!/bin/bash # run-parts - concept taken from Debian
    ............
    for i in $1/* ; do
    [ -d $i ] && continue
    if [ -x $i ]; then
    $i
    fi
    done
    exit 0

Proposition de corrigés

  • Toto dit bonjour
    toto étant un utilisateur autorisé 
    $ crontab -e
    # toto ajoute la ligne (echo -n inhibe le passage à la ligne) :
    */5 * * * * (echo -n Bonjour ! nous sommes le ;date ) >> /tmp/bonjour.txt
  • root surveille ...
    0 9-17  * * 1-5 (ps aux ; echo "***************" ) >> /var/log/processus.txt
    */15 9-17 * * 1-5 who >> /var/log/qui.txt
  • root sauvegarde les rep. personnels
    #!/bin/bash
    # fichier sauve_home.sh

    date=$(date)
    set -- $date
    tar czvf /var/sauve/home.$3$2$6.tgz /home/*

    # extrait de crontab de root (fichier /etc/spool/cron/root)
    0 1 * * * /var/home/sauve_home.sh
  • Vérifier que samba est toujours en cours d'exécution (Ph Chadefaux)
    #!/bin/sh
    # script surveille_smb
    /sbin/pidof smbd > /dev/null
    if [ $? = 1 ]
    then
    /etc/rc.d/init.d/smb stop
    /etc/rc.d/init.d/smb start
    echo "Redémarrage de samba" | mail -s "[SAMBA]" root@p0x.fctice77.fr
    fi

    # fichier crontab
    */2 * * * * /bin/surveille_smb

  • Contrôler si la ligne ADSL est toujours montée (Ph Chadefaux)
    #!/bin/sh

    # script reconnexion.sh
    if ! ping -c 1 195.98.246.50 > /dev/null 2>&1

    then
    /usr/bin/killall pppd pppoe
    sleep 40
    /usr/sbin/pppoe 10.0.0.138
    fi
    # extrait de la crontab de root
    */3 * * * * /bin/reconnexion.sh
    On ping une machine de l'internet, par exemple 195.98.246.50.

    Si on n'a pas de réponse on "kill" pppd et pppoe et on relance pppoe (10.0.0.138 est l'adresse IP
    du modem adsl par défaut)