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.
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
MAILTOcontient une adresse, cron envoie les emails à cette adresse ; - si
MAILTO="", cron n’envoie pas d’email ; - si
MAILTOn’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/nullsupprime la sortie standard ;2>&1redirige la sortie d’erreur vers la sortie standard ;- donc
stdoutetstderrdisparaissent.
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.
Vos mises à jour vous font peur ?
PHP 8.x qui casse un plugin, un thème qui n'est plus maintenu, une mise à jour de WooCommerce qui change tout — je gère les montées de version proprement, avec environnement de staging et rollback prévu.
Mettons votre stack à jour sans risque →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
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 :
| Flux | Descripteur | Usage |
|---|---|---|
stdout | 1 | messages normaux, résultats, logs non critiques |
stderr | 2 | erreurs, avertissements importants, échecs |
Les redirections les plus utiles sont :
| Redirection | Effet |
|---|---|
> /dev/null | supprime uniquement stdout |
2> /dev/null | supprime uniquement stderr |
> /dev/null 2>&1 | supprime stdout et stderr |
>> fichier.log | ajoute stdout à un fichier |
>> fichier.log 2>&1 | ajoute 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
stdoutvers un log ; - garder
stderrpour 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
flockpour é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
stdoutetstderr. - 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 -letsudo crontab -l. - Vérifier
/etc/crontabet/etc/cron.d/. - Identifier les tâches qui écrivent inutilement sur
stdout. - Corriger les scripts trop bavards.
- Rediriger
stdoutvers/dev/nullsi seules les erreurs comptent. - Rediriger
stdoutetstderrvers 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
flockaux 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
- Linux man-pages : crontab(5)
- Linux man-pages : cron(8)
- systemd.timer : documentation officielle
- Linux man-pages : flock(1)
- SkyMinds : mettre en cache WordPress pour accélérer son site
- SkyMinds : auditer les lenteurs WordPress avec wp profile
- SkyMinds : installer Redis pour accélérer WordPress sous Debian
Besoin d'un coup de main ?
Ce bug qui traîne depuis des semaines, ce plugin qui casse votre mise en page, cette fonctionnalité que personne n'arrive à implémenter proprement — c'est exactement ce que je règle au quotidien depuis 20 ans.
Parlons de votre problème →

