Login Logout

Howto Cron

Le service cron (diminutif de crontab, pour chrono table) est le planificateur de tâches standard sur les systèmes UNIX/Linux. Il permet le déclenchement de commandes à des dates récurrentes et à la minute près.

Installation

Très souvent, on le retrouve déjà installé :

# systemctl status cron
● cron.service - Regular background program processing daemon
   Loaded: loaded (/lib/systemd/system/cron.service; enabled; vendor preset: enabled)
     Docs: man:cron(8)
 Main PID: 492 (cron)
   CGroup: /system.slice/cron.service
           └─492 /usr/sbin/cron -f

Sinon, la commande suivante permet de l’obtenir :

apt install cron

Configuration

Les paramètres principaux sont définit dans le fichier /etc/crontab :

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name command to be executed
17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )

On observe que :

  • Le shell par défaut sera /bin/sh
  • Les tâches crons auront un accès facilité à l’ensemble de répertoires où se trouvent les programmes exécutables.
  • Des dates sont définies pour exécuter des actions inclus dans les répertoires dédiés /etc/cron.*.

D’autres options de configurations peuvent être pris en charge par défaut pour toutes les tâches crons via le fichier /etc/default/cron. Notamment en ce qui concerne le niveau de verbosité de la journalisation, définir des variables d’environnements, etc.

Cas d’usage

Les dossiers /etc/cron.* et /etc/cron.d/

Pour lancer un script à une date précise : il suffit de le rendre exécutable et de le placer dans l’un des répertoires /etc/cron.* en fonction de la fréquence souhaitée.

Pour lancer un script à une fréquence personnalisée : il suffit de créer un nouveau fichier pour le placer dans /etc/cron.d/ incluant une suite de paramètres pour indiquer la fréquence et l’utilisateur qui doit lancer la commande, par exemple :

30 05 * * 0 www-data /usr/local/adm/savelog

Attention : En cas d’erreur de syntaxe dans un script, toutes les autres tâches crons du même répertoire ne seront pas lancés ! Il faut donc réserver cette utilisation à des scripts bien vérifiés!

Attention : Les noms de scripts contenant des points sont ignorés. Cette particularité est utile pour désactiver un script en ajoutant .disabled comme extension.

La commande crontab

Cette commande permet d’éditer/lister/supprimer les tâches planifiées gérées par le service cron et sont automatiquement liées à des comptes utilisateurs. Elles sont conservées dans /var/spool/cron/. L’avantage de cette commande est la vérification syntaxique en quittant l’éditeur.

Pour ajouter une tâche cron :

crontab -e

Attention : Méfiez-vous de la touche “r” qui est proche de la touche “e” sur un clavier Azerty ou Qwerty où crontab -r efface définitivement toute votre crontab!

Pour lister les tâches cron :

crontab -l

La syntaxe

Attention: La syntax des fichiers dans /etc/cron.d/ est différente et nécessite un nom d’utilisateur entre le temps d’exécution et la commande.

On peut s’aider de crontab guru pour être sûr de ne pas faire d’erreur sur l’horaire.

Plus en détail, la syntaxe complète est :

minutes heures jours mois jour/semaine commande

On peut utiliser * pour toutes les occurrences (tous les jours, ou toutes les heures, etc.). On peut également utiliser des listes à virgule (3,5,7) ainsi des intervalles (2-6) ; on peut aussi avoir des intervalles réguliers (*/15).

Exemples de crontab :

0,30,45,51 * * * * /usr/local/adm/send-data
*/15 * * * * /usr/local/adm/check-nis 1>/dev/null 2>&1
00 01 * * * nice -10 find /inf -name core -exec rm -f {} \;
10 03 * * 1-6 nice -10 /usr/local/adm/sauvegarde-daily
30 05 * * 0 /usr/local/adm/savelog-weekly
30 06 1 * * /usr/local/adm/savelog-monthly
00 00 1 1 * /usr/local/bin/happy-new-year
@daily /usr/local/bin/minuit-check

On peut utiliser les mots clés @hourly/@daily/@weekly/@monthly pour lancer à la première minute de chaque heure/jour/semaine/mois (à ne pas confondre avec les répertoires /etc/cron.* qui sont lancés à des dates particulières).

Pour plus de détails sur les recommandations sur l’écriture de scripts à mettre en crontab voir TipsDevWeb#scripts-en-crontab.

Les Variables

Plusieurs variables peuvent être utilisées dans une crontab :

PATH : redéfinir le PATH des commandes lancés

SHELL : remplacer le shell /bin/sh utilisé par défaut par /bin/bash par exemple

MAILTO : Un email est envoyé à l’utilisateur lorsqu’une commande génère une sortie (stdout/stderr). On peut changer le destinataire ainsi qu’en mettre plusieurs ou empêcher l’envoi d’un message avec MAILTO="".

Ces variables peuvent être définies plusieurs fois, notamment MAILTO qui pourra précéder chaque ligne de cron :

MAILTO=jdoe@example.com,alert@example.com
@daily df -h
MAILTO=""
@hourly systemctl restart javajob
MAILTO=alert@example.com
@weekly /usr/local/bin/security-check

cronic

cronic est un wrapper shell pour les tâches cron qui améliore cron en évitant l’envoi de courriels bruiyant par cron.

Il envoie un email uniquement lorsqu’une erreur se produit dans un job cron, en filtrant les erreurs et les traces d’exécution pour un débogage plus facile. Il remplace la redirection classique de la sortie vers /dev/null pour permettre la détection des erreurs importantes sans spam.

Ça s’utilise comme ça dans une tâche cron :

0 1 * * * cronic backup

log2mail

On peut ajouter la configuration suivante au logiciel log2mail pour détecter d’éventuelles erreurs de syntaxe :

file = /var/log/cron.log
  pattern = "Error"
  mailto = root

FAQ

Peut-on écrire un cron dans /etc/crontab ?

Si l’on a joute une ligne de cron, elle sera exécutée par Root mais on déconseille fortement cette utilisation car:

  • Ce fichier de configuration doit rester intact autant que possible pour faciliter les mises à jour du système.
  • On évite autant que l’on peut de lancer un cron en tant que root par principe de sécurité.
  • La moindre erreur de syntaxe provoquera la non-exécution de tous les autres scripts !

Changement d’heure

Lors d’un changement d’heure d’été ou d’hiver en France où un script est planifié pour être exécuté entre 2h et 3h du matin, il peut être lancé deux fois! Le service cron sait détecter ce souci mais par précaution, on évite d’en établir durant cette tranche horaire.

Échappement de caractères

Prenons l’exemple d’une copie horodatée de /etc chaque heure :

@hourly root tar -cf /home/backup/etc-$(date +%H).tar /etc

Celle-ci ne sera pas exécutée car le caractère % est interprété comme un saut de ligne où la commande sera incomplète et donc non fonctionnelle.

La correction s’applique en échappant le % avec un \ :

@hourly root tar -cf /home/backup/etc-$(date +\%H).tar /etc