How to Configure Cron to Email Only Errors (Suppress Success Notifications)


2 views

If you've set up frequent cron jobs for critical tasks like backups, you've likely encountered the frustration of receiving empty or "success" emails every time the job runs. While monitoring is important, getting spammed with notifications when everything works fine is counterproductive.

Cron's default behavior is to email the output of every job to the MAILTO address (or system user if unspecified). The common pattern:

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

Will send output regardless of success/failure status.

Here are three effective approaches to suppress success emails:

1. The Exit Code Check

Modify your script to only produce output on errors:

#!/bin/bash
# backup.sh
if ! tar -czf /backups/data-$(date +%Y%m%d).tar.gz /important_data; then
    echo "Backup failed with exit code $?"
    exit 1
fi
exit 0

2. The Wrapper Method

Create a wrapper that filters output:

#!/bin/bash
# cron-wrapper.sh
output=$(/bin/backup.sh 2>&1)
exitcode=$?
if [ $exitcode -ne 0 ]; then
    echo "$output" | mail -s "Backup FAILED" email@example.com
fi
exit $exitcode

Then update your crontab:

0 */2 * * * /bin/cron-wrapper.sh

3. The Logfile Approach

For more sophisticated monitoring:

0 */2 * * * /bin/backup.sh >> /var/log/backup.log 2>&1 || \
    (cat /var/log/backup.log | mail -s "Backup Error" email@example.com)

For Linux systems using Postfix or similar, you can configure cron to only email on errors system-wide by adding to /etc/rsyslog.conf:

cron.* /var/log/cron.log
cron.!error /dev/null

Then restart syslog and cron services.

Always verify your setup by:

# Force success
/bin/backup.sh
# Force failure
/bin/backup.sh && false

Check your mailbox only receives the failure notification.


If you've set up cron jobs for critical tasks like backups, you've probably encountered the frustration of receiving emails for every single execution - even when everything works perfectly. Here's a deeper look at the issue and how to solve it properly.

Your current crontab entry:

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

This configuration sends all output (both stdout and stderr) to your email, which explains why you're getting empty messages when the backup succeeds.

There are several approaches to solve this. Let me show you the most robust methods:

Method 1: Conditional Email Sending

Modify your script to only produce output on errors:

#!/bin/bash
# backup.sh
if ! tar -czf /backups/data-$(date +%Y%m%d).tar.gz /important/data; then
    echo "Backup failed on $(date)"
    exit 1
fi

Then update your crontab:

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

Method 2: Using MAILTO with Proper Exit Codes

First, set MAILTO in your crontab:

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

Then modify your script to use proper exit codes:

#!/bin/bash
# backup.sh
tar -czf /backups/data-$(date +%Y%m%d).tar.gz /important/data || exit 1
exit 0

For more complex scenarios where you want logs but only error notifications:

#!/bin/bash
LOG_FILE=/var/log/backup.log
exec > >(tee -a "$LOG_FILE")
exec 2>&1

# Main backup command
if ! tar -czf /backups/data-$(date +%Y%m%d).tar.gz /important/data; then
    echo "[ERROR] Backup failed at $(date)"
    exit 1
fi
echo "[INFO] Backup completed successfully at $(date)"
exit 0

Crontab entry:

0 */2 * * * /bin/backup.sh && true || mail -s "Backup Error" email@example.com < /var/log/backup.log

Remember that:

  • Cron's email behavior depends on your MTA configuration
  • Some systems have cron-specific log files at /var/log/cron
  • For critical systems, consider adding monitoring beyond just email
  • Test your error conditions thoroughly