Désactiver les emails cron sans perdre les erreurs utiles

Par défaut, une tâche cron sous Linux peut envoyer un email dès qu’elle produit une sortie. Cela concerne aussi bien la sortie standard stdout que la sortie d’erreur stderr.

Sur un serveur, ce comportement peut être utile. Une erreur nocturne dans une sauvegarde, un script de maintenance ou une tâche WordPress mérite souvent votre attention. Mais quand une tâche affiche simplement “OK”, “done” ou une ligne de log à chaque exécution, votre boîte mail devient vite un vide-grenier automatisé.

Voici comment désactiver les emails cron inutiles, tout en gardant les erreurs importantes quand c’est possible.

Kinsta: Premium Managed WordPress hosting

Pourquoi cron envoie-t-il des emails ?

Cron exécute une commande à l’heure prévue. Si cette commande écrit quelque chose sur stdout ou stderr, cron tente d’envoyer cette sortie par email au propriétaire du crontab.

Le destinataire dépend de la variable MAILTO :

  • si MAILTO contient une adresse, cron envoie les emails à cette adresse ;
  • si MAILTO="", cron n’envoie pas d’email ;
  • si MAILTO n’est pas défini, cron envoie les emails à l’utilisateur propriétaire du crontab.

Ce comportement est documenté dans crontab(5) : si MAILTO est défini mais vide, aucun email n’est envoyé. Sinon, cron envoie la sortie au destinataire configuré ou au propriétaire du crontab.

Si aucun agent mail local n’est installé, vous pouvez voir dans les logs un message du type :

(CRON) info (No MTA installed, discarding output)

Dans ce cas, cron essaie bien d’envoyer une sortie, mais le système n’a pas de service mail local pour la distribuer.

Avant de couper les emails : identifiez le bruit

Avant de rendre toutes les tâches cron muettes, commencez par voir ce qui tourne réellement.

Pour le crontab de l’utilisateur courant :

crontab -l

Pour le crontab de root :

sudo crontab -l

Vérifiez aussi les emplacements système :

cat /etc/crontab
ls -lah /etc/cron.d/
ls -lah /etc/cron.daily/
ls -lah /etc/cron.hourly/
ls -lah /etc/cron.weekly/
ls -lah /etc/cron.monthly/

Sur Debian et Ubuntu, les logs cron se retrouvent souvent dans /var/log/syslog. Sur RHEL, Rocky, AlmaLinux, CentOS ou Fedora, regardez plutôt /var/log/cron.

grep CRON /var/log/syslog | tail -n 50Langage du code : JavaScript (javascript)
sudo tail -n 50 /var/log/cronLangage du code : JavaScript (javascript)

L’objectif est simple : couper les notifications inutiles, pas enterrer les erreurs sous le tapis. Le tapis finit toujours par sentir le cron brûlé.

Solution 1 : supprimer toute sortie avec /dev/null

La méthode la plus connue consiste à rediriger toute la sortie vers /dev/null.

0 1 * * * /home/user/script.sh > /dev/null 2>&1Langage du code : JavaScript (javascript)

Explication :

  • > /dev/null supprime la sortie standard ;
  • 2>&1 redirige la sortie d’erreur vers la sortie standard ;
  • donc stdout et stderr disparaissent.

Cette solution coupe les emails, mais elle coupe aussi les erreurs. Je l’utilise seulement pour des tâches vraiment triviales, ou quand un autre système de monitoring surveille déjà le résultat.

Exemple acceptable :

*/10 * * * * /usr/bin/php /var/www/site/current/wp-cron.php > /dev/null 2>&1Langage du code : JavaScript (javascript)

Même là, sur un site critique, je préfère logger les erreurs. WordPress peut être bavard, mais il ne faut pas bâillonner le messager quand il annonce un incendie.

Solution 2 : supprimer stdout, garder les erreurs par email

Souvent, la meilleure solution consiste à supprimer uniquement la sortie normale et à garder les erreurs.

0 1 * * * /home/user/backup.sh > /dev/nullLangage du code : JavaScript (javascript)

Ici, stdout part vers /dev/null, mais stderr reste disponible. Si le script écrit une erreur sur stderr, cron peut encore envoyer un email.

C’est souvent le meilleur compromis pour les tâches importantes : sauvegardes, synchronisations, renouvellements de certificats, exports, traitements WooCommerce, scripts de maintenance ou tâches serveur.

Encore faut-il que vos scripts respectent cette convention :

  • les messages normaux vont vers stdout ;
  • les erreurs vont vers stderr ;
  • le script retourne un code de sortie non nul en cas d’échec.

Un bon script silencieux en succès et explicite en erreur vaut mieux qu’un script enthousiaste qui écrit “Tout va bien” toutes les cinq minutes. Merci, mais non merci.

Kinsta: Premium Managed WordPress hosting

Solution 3 : écrire stdout dans un log et garder stderr par email

Pour les tâches importantes, vous pouvez envoyer la sortie normale dans un fichier de log, tout en gardant les erreurs par email.

0 2 * * * /home/user/backup.sh >> /var/log/backup.logLangage du code : JavaScript (javascript)

Cette commande ajoute la sortie standard au fichier /var/log/backup.log. Les erreurs restent sur stderr, donc cron peut encore les envoyer par email.

Si votre utilisateur n’a pas le droit d’écrire dans /var/log, utilisez un dossier de logs dédié :

mkdir -p /home/user/logs
0 2 * * * /home/user/backup.sh >> /home/user/logs/backup.logLangage du code : JavaScript (javascript)

Vous pouvez ensuite ajouter une rotation avec logrotate, sinon votre fichier de log deviendra un roman russe. Long, dense, et difficile à ouvrir à 3 h du matin.

Solution 4 : tout écrire dans un log, sans email

Si vous voulez supprimer les emails mais conserver une trace complète, redirigez stdout et stderr vers un fichier.

0 2 * * * /home/user/backup.sh >> /home/user/logs/backup.log 2>&1Langage du code : JavaScript (javascript)

Ici, tout part dans le log :

  • sortie normale ;
  • messages d’erreur ;
  • avertissements ;
  • traces utiles au diagnostic.

C’est souvent préférable à /dev/null. Vous ne recevez plus d’email, mais vous gardez de quoi comprendre ce qui s’est passé.

Pour consulter les dernières lignes :

tail -n 100 /home/user/logs/backup.log

Pour suivre le log en direct :

tail -f /home/user/logs/backup.log
Kinsta: Premium Managed WordPress hosting

Solution 5 : désactiver tous les emails avec MAILTO= » »

Pour désactiver tous les emails d’un crontab, ajoutez MAILTO="" au début du fichier.

Ouvrez le crontab :

crontab -e

Ajoutez en haut :

MAILTO=""Langage du code : JavaScript (javascript)

Exemple :

MAILTO=""

0 1 * * * /home/user/script-1.sh
0 2 * * * /home/user/script-2.sh
0 3 * * * /home/user/script-3.shLangage du code : JavaScript (javascript)

Cette solution désactive les emails pour toutes les tâches de ce crontab. Elle est pratique, mais assez brutale. Si une tâche échoue et écrit une erreur, vous ne recevrez rien par email.

Je recommande donc de l’utiliser seulement si vos tâches écrivent dans des logs, ou si un monitoring externe surveille les échecs.

Envoyer les emails cron vers une adresse précise

Plutôt que de désactiver les emails, vous pouvez les envoyer à une adresse précise :

MAILTO="admin@example.com"Langage du code : JavaScript (javascript)

Selon l’implémentation de cron, plusieurs destinataires peuvent être séparés par des virgules :

MAILTO="admin@example.com,devops@example.com"Langage du code : JavaScript (javascript)

Gardez toutefois une règle simple : les emails cron doivent aller vers une boîte surveillée. Une alerte envoyée à une boîte jamais lue n’est pas une alerte. C’est une décoration murale pour serveur.

Désactiver les emails seulement pour une tâche

Si une seule tâche est trop bavarde, ne désactivez pas tout le crontab. Corrigez seulement cette ligne.

Avant :

* * * * * /home/user/noisy-script.shLangage du code : JavaScript (javascript)

Après, si vous voulez tout supprimer :

* * * * * /home/user/noisy-script.sh > /dev/null 2>&1Langage du code : JavaScript (javascript)

Après, si vous voulez garder les erreurs :

* * * * * /home/user/noisy-script.sh > /dev/nullLangage du code : JavaScript (javascript)

Après, si vous voulez garder un log complet :

* * * * * /home/user/noisy-script.sh >> /home/user/logs/noisy-script.log 2>&1Langage du code : JavaScript (javascript)

Dans la majorité des cas, c’est cette correction ligne par ligne que je préfère.

Comprendre stdout et stderr en cron

Une tâche cron peut écrire sur deux sorties principales :

FluxDescripteurUsage
stdout1messages normaux, résultats, logs non critiques
stderr2erreurs, avertissements importants, échecs

Les redirections les plus utiles sont :

RedirectionEffet
> /dev/nullsupprime uniquement stdout
2> /dev/nullsupprime uniquement stderr
> /dev/null 2>&1supprime stdout et stderr
>> fichier.logajoute stdout à un fichier
>> fichier.log 2>&1ajoute stdout et stderr au même fichier

Note importante : l’ordre compte. Cette redirection est correcte :

commande > fichier.log 2>&1Langage du code : CSS (css)

Elle signifie : envoie stdout vers le fichier, puis envoie stderr au même endroit que stdout.

Tester une tâche cron manuellement

Avant de modifier le crontab, testez la commande manuellement avec le même utilisateur.

Si la tâche appartient à votre utilisateur :

/home/user/script.sh

Si la tâche appartient à root :

sudo /home/user/script.sh

Pour voir ce qui sort sur stdout et stderr, testez :

/home/user/script.sh > /tmp/stdout.log 2> /tmp/stderr.log

cat /tmp/stdout.log
cat /tmp/stderr.logLangage du code : JavaScript (javascript)

Si le script écrit des messages normaux dans stderr, corrigez le script plutôt que cron. Cron ne fait que transmettre ce qu’on lui donne. Il n’est pas devin. Dommage, cela aurait été pratique.

Cas WordPress : désactiver les emails cron de wp-cron.php

Sur un site WordPress, on remplace souvent le pseudo-cron intégré par une vraie tâche système. Dans wp-config.php, on désactive d’abord WP-Cron au chargement des pages :

define( 'DISABLE_WP_CRON', true );Langage du code : JavaScript (javascript)

Puis on ajoute une tâche cron système :

*/5 * * * * /usr/bin/php /var/www/example.com/htdocs/wp-cron.php > /dev/null 2>&1Langage du code : JavaScript (javascript)

Cette ligne est fréquente, mais elle masque toutes les erreurs. Pour un site critique, je préfère écrire les erreurs dans un log dédié :

*/5 * * * * /usr/bin/php /var/www/example.com/htdocs/wp-cron.php > /dev/null 2>> /var/log/wp-cron-example.com.errLangage du code : JavaScript (javascript)

Ou tout journaliser :

*/5 * * * * /usr/bin/php /var/www/example.com/htdocs/wp-cron.php >> /var/log/wp-cron-example.com.log 2>&1Langage du code : JavaScript (javascript)

Si vous gérez beaucoup de sites WordPress, utilisez un log par site. Le jour où une tâche WooCommerce ou Action Scheduler bloque, vous serez heureux de ne pas fouiller un compost global de 400 Mo.

Utiliser flock pour éviter les tâches cron qui se chevauchent

Une autre cause de bruit vient des tâches qui durent plus longtemps que prévu. Si une tâche tourne toutes les cinq minutes mais met dix minutes à finir, plusieurs instances peuvent se chevaucher.

Utilisez flock pour empêcher ce chevauchement :

*/5 * * * * /usr/bin/flock -n /tmp/wp-cron-example.lock /usr/bin/php /var/www/example.com/htdocs/wp-cron.php > /dev/null 2>> /var/log/wp-cron-example.errLangage du code : JavaScript (javascript)

L’option -n indique à flock de ne pas attendre si le verrou existe déjà. La nouvelle exécution est simplement ignorée si l’ancienne tourne encore.

Pour les tâches de sauvegarde, d’import ou de synchronisation, c’est souvent indispensable.

Configurer crond globalement avec -m off ou -s

Sur certaines distributions utilisant Cronie, vous pouvez modifier le comportement global de crond. Historiquement, on pouvait trouver cela dans /etc/sysconfig/crond :

CRONDARGS="-m off"Langage du code : JavaScript (javascript)

L’option -m off désactive l’envoi des emails par crond. L’option -s peut envoyer la sortie vers les logs système, selon l’implémentation et la distribution.

Je déconseille cette approche comme premier réflexe. Elle agit globalement sur le service cron. Si vous hébergez plusieurs sites, plusieurs utilisateurs ou plusieurs tâches critiques, vous risquez de couper des alertes utiles pour tout le serveur.

Préférez d’abord :

  • corriger les scripts trop bavards ;
  • rediriger stdout vers un log ;
  • garder stderr pour les erreurs ;
  • utiliser MAILTO="" seulement sur les crontabs concernés.

systemd timers : une alternative moderne à cron

Sur les distributions modernes, les timers systemd peuvent remplacer certaines tâches cron. Un timer systemd déclenche un service à une heure donnée, avec une meilleure intégration aux logs via journalctl.

La documentation systemd indique qu’une unité .timer déclenche une unité .service associée. Les timers peuvent utiliser des déclenchements calendaires avec OnCalendar. :contentReference[oaicite:1]{index=1}

Exemple minimal de service :

# /etc/systemd/system/example-backup.service
[Unit]
Description=Example backup job

[Service]
Type=oneshot
ExecStart=/usr/local/bin/example-backup.shLangage du code : PHP (php)

Timer associé :

# /etc/systemd/system/example-backup.timer
[Unit]
Description=Run example backup every night

[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true

[Install]
WantedBy=timers.targetLangage du code : PHP (php)

Activez le timer :

sudo systemctl daemon-reload
sudo systemctl enable --now example-backup.timerLangage du code : CSS (css)

Vérifiez les timers :

systemctl list-timersLangage du code : PHP (php)

Consultez les logs :

journalctl -u example-backup.serviceLangage du code : CSS (css)

Les timers systemd sont excellents pour les tâches système importantes. Pour un simple hébergement mutualisé ou une petite tâche utilisateur, cron reste souvent plus simple.

Ne confondez pas silence et succès

Un cron silencieux n’est pas forcément un cron qui fonctionne. Il peut échouer sans rien dire si vous avez redirigé les erreurs vers /dev/null.

Pour une tâche importante, prévoyez au moins une de ces protections :

  • un log dédié ;
  • un email uniquement sur erreur ;
  • un monitoring externe ;
  • une vérification du code de sortie ;
  • une alerte si le fichier attendu n’est pas créé ;
  • une rotation de logs ;
  • un verrou flock pour éviter les chevauchements.

Pour une sauvegarde, par exemple, ce n’est pas le mail qui compte. C’est la restauration. Testez donc régulièrement vos backups. Le cron peut être silencieux, le désastre aussi.

Exemples prêts à copier

Tâche totalement silencieuse :

0 1 * * * /home/user/script.sh > /dev/null 2>&1Langage du code : JavaScript (javascript)

Tâche silencieuse en succès, email en cas d’erreur :

0 1 * * * /home/user/script.sh > /dev/nullLangage du code : JavaScript (javascript)

Tâche avec log complet, sans email :

0 1 * * * /home/user/script.sh >> /home/user/logs/script.log 2>&1Langage du code : JavaScript (javascript)

Tâche avec stdout dans un log et erreurs par email :

0 1 * * * /home/user/script.sh >> /home/user/logs/script.logLangage du code : JavaScript (javascript)

Désactiver les emails pour tout le crontab :

MAILTO=""Langage du code : JavaScript (javascript)

Envoyer les emails à une adresse précise :

MAILTO="admin@example.com"Langage du code : JavaScript (javascript)

Tâche WordPress avec erreurs dans un log :

*/5 * * * * /usr/bin/php /var/www/example.com/htdocs/wp-cron.php > /dev/null 2>> /var/log/wp-cron-example.com.errLangage du code : JavaScript (javascript)

Tâche protégée contre les chevauchements :

*/5 * * * * /usr/bin/flock -n /tmp/example.lock /home/user/script.sh >> /home/user/logs/script.log 2>&1Langage du code : JavaScript (javascript)

Besoin d’aide pour fiabiliser vos tâches cron ?

Besoin d’aide pour nettoyer vos crons serveur ?

Si votre serveur vous envoie des emails cron en boucle, ou si vos tâches WordPress, sauvegardes, certificats SSL ou scripts de maintenance tournent sans vraie supervision, je peux vous aider à remettre tout ça au propre.

J’interviens sur les serveurs Linux et WordPress pour auditer les crons, réduire le bruit, conserver les erreurs utiles, ajouter des logs exploitables, éviter les tâches qui se chevauchent et fiabiliser les automatisations critiques.

  • Audit des crontabs utilisateur, root et /etc/cron.d.
  • Redirections propres de stdout et stderr.
  • Logs dédiés, rotation, alertes et monitoring.
  • Protection contre les chevauchements avec flock.
  • Migration de tâches critiques vers systemd timers si utile.

Vous voulez un serveur silencieux sans devenir aveugle aux vraies erreurs ? Contactez-moi. Je vous aiderai à garder les alertes utiles et à supprimer le bruit.

Checklist de configuration cron

  • Lister les crontabs avec crontab -l et sudo crontab -l.
  • Vérifier /etc/crontab et /etc/cron.d/.
  • Identifier les tâches qui écrivent inutilement sur stdout.
  • Corriger les scripts trop bavards.
  • Rediriger stdout vers /dev/null si seules les erreurs comptent.
  • Rediriger stdout et stderr vers un log si vous ne voulez plus d’email.
  • Utiliser MAILTO="" seulement si vous avez un autre système de suivi.
  • Garder les erreurs visibles pour les tâches critiques.
  • Ajouter flock aux tâches longues.
  • Prévoir une rotation des logs.
  • Tester les scripts avec le même utilisateur que cron.
  • Vérifier régulièrement que les tâches critiques produisent le résultat attendu.

FAQ : emails cron sous Linux

Pourquoi cron m’envoie-t-il des emails ?

Cron envoie un email quand une tâche produit une sortie sur stdout ou stderr. Si MAILTO est défini, le mail part vers cette adresse. Sinon, il part vers l’utilisateur propriétaire du crontab.

Comment désactiver tous les emails d’un crontab ?

Ajoutez MAILTO="" au début du crontab. Cela coupe les emails pour toutes les tâches de ce crontab. À utiliser avec prudence si vous n’avez pas de logs ou de monitoring.

Comment désactiver les emails pour une seule tâche cron ?

Ajoutez une redirection à la ligne concernée. Pour tout supprimer : > /dev/null 2>&1. Pour garder les erreurs par email : > /dev/null.

Quelle différence entre > /dev/null et > /dev/null 2>&1 ?

> /dev/null supprime seulement la sortie normale. > /dev/null 2>&1 supprime la sortie normale et les erreurs. La seconde option rend la tâche complètement silencieuse.

Pourquoi je vois “No MTA installed, discarding output” ?

Cron a capturé une sortie et a tenté de l’envoyer par email, mais aucun agent mail local n’est installé. Vous pouvez soit installer/configurer un MTA, soit rediriger correctement la sortie de la tâche.

Faut-il remplacer cron par systemd timers ?

Pas toujours. Cron reste simple et efficace. Les timers systemd sont intéressants pour les tâches système importantes, car ils s’intègrent mieux avec systemctl, journalctl, les dépendances et les exécutions persistantes.

Sources

Demandez à l'IA son opinion
Gravatar for Matt Biscay

Je suis Matt Biscay, développeur WordPress & WooCommerce certifié chez Codeable, administrateur système et enseignant.

J’aide les entreprises à créer, optimiser et fiabiliser leurs sites WordPress avec une approche technique propre : performance, sécurité, maintenance, développement sur mesure et résolution de problèmes complexes.

Sur Skyminds, je partage des tutoriels WordPress, WooCommerce, Linux et administration système, avec des solutions testées sur des cas réels et pensées pour durer.

Découvrez mes services WordPress et WooCommerce.

Laisser un commentaire