Cron: Seulement obtenir des erreurs dans les emails?

39

J'ai finalement mis en place un programme de sauvegarde réaliste de mes données via un script shell, géré par cron à intervalles rapprochés. Malheureusement, je reçois des courriels vides chaque fois que le CRON a été exécuté et pas seulement lorsque les choses tournent mal.

Est-il possible de faire en sorte que CRON envoie des courriels en cas de problème, par exemple. monTAR ne pas exécuter comme prévu?

Voici comment ma crontab est configurée pour le moment;

0 */2 * * * /bin/backup.sh 2>&1 | mail -s "Backup status" email@example.com

Merci beaucoup!

Industriel
la source

Réponses:

54

Idéalement, vous voudriez que votre script de sauvegarde ne génère rien si tout se passe comme prévu et ne produit une sortie que lorsque quelque chose ne va pas. Utilisez ensuite la variable d’environnement MAILTO pour envoyer toute sortie générée par votre script à votre adresse électronique.

MAILTO=email@example.com
0 */2 * * * /bin/backup.sh

Si votre script produit normalement une sortie mais que vous ne vous en souciez pas dans cron, envoyez-le simplement à / dev / null et il vous n'enverra un e-mail que lorsque quelque chose aura été écrit dans stderr.

MAILTO=email@example.com
0 */2 * * * /bin/backup.sh > /dev/null
Cakemox
la source
9
C'est loin d'être idéal. Vous souhaitez généralement recevoir la totalité de la sortie (stdout + stderr) par courrier électronique lorsque la commande se termine par un code d'erreur différent de zéro. Sinon, il est généralement préférable d’avaler au moins stdout. Pour moi, ceci est un défaut de conception de cron.
Witiko
3
@Witiko je suis d'accord; J'ai trouvé cette question en essayant de résoudre ce problème. Je suppose que vous pouvez faire votre commande cron /bin/backup.sh > log_file || (echo Backup failed with exit status $?; cat log_file)?
Daniel H
23

L' utilisation de script wrapper cronic semble être une bonne idée; pour l'utiliser, vous n'avez pas à changer vos scripts.

Au lieu de:

 0 1 * * * /bin/backup.sh 2>&1 | mail -s "Backup status" email@example.com

faire:

 MAILTO=email@example.com
 0 1 * * * cronic /bin/backup.sh

Tout simplement; il fonctionnera en mode silencieux si tout se passe bien (état de sortie 0), mais il signalera verbalement sinon, et laissera cron gérer les rapports de messagerie.

Plus d'informations sur https://habilis.net/cronic/ .

Ricardo Pardini
la source
Je ne vois vraiment pas comment cela aiderait lorsque le problème n'est rien d'autre qu'une ligne de cron incorrecte et que cron fait exactement ce qu'on lui dit de faire.
John Gardeniers
3
@JohnGardeniers cela aide car parfois vous avez une sortie sans erreur.
Mikhail
11
Alternativement, à chronicpartir du moreutilspackage: joeyh.nom
Vladimir Panteleev
4

Vous demandez spécifiquement cronà toujours envoyer un courrier électronique, même si /bin/backup.sh(à propos, il devrait être en place /usr/local/bin) réussit. Il suffit d'omettre la | mail -s "Backup status" [email protected]pièce et le courrier électronique ne sera envoyé que s'il y a une sortie. Vous pouvez probablement (en fonction de votre cron) définir explicitement l’adresse email à mail en tant qu’affectation dans le fichier crontab.

Pour plus de détails, voir

man 5 crontab
Reinierpost
la source
3

Vous devriez diriger les stderranmd pas les deux stdoutet stderr.

1> /dev/nullNe l' utilisez pas 2>&1et ça devrait aller. En outre, vous devrez peut-être signaler l'erreur correctement dans votre script de sauvegarde.

Khaled
la source
3

Voici une autre variante que j'utilise avec succès depuis de nombreuses années: capturer la sortie et l'imprimer uniquement en cas d'erreur entraînant l'envoi d'un courrier électronique. Cela ne nécessite aucun fichier temporaire et conserve toutes les sorties . La partie importante est celle 2>&1qui redirige STDERR vers STDOUT.

Envoyez la totalité de la sortie via la configuration par défaut de cron mailer:

1 2 * * * root OUTPUT=`flexbackup -set all 2>&1` || echo "$OUTPUT"

Identique mais avec une adresse et un sujet spécifiques:

(l'adresse peut également être modifiée en définissant MAILTO = xxxx pour l'ensemble du fichier crontab)

1 2 * * * root OUTPUT=`flexbackup -set all 2>&1` || echo "$OUTPUT" | mail -s "Failed to backup" an@email.address

Vous pouvez même effectuer plusieurs actions en cas d'erreur et ajouter à un courrier électronique:

1 2 * * * root OUTPUT=`flexbackup -set all 2>&1` || {echo "$OUTPUT" ; ls -ltr /backup/dir ; }

Cela fonctionnera pour des commandes simples. Si vous find / -type f | grep -v bla | tar something-or-otherutilisez des tubes complexes ( ), il est préférable de déplacer la commande dans un script et de l'exécuter en utilisant l'approche susmentionnée. La raison en est que si une partie du tuyau est transmise à STDERR, vous aurez toujours des courriels.

Akom
la source