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