M0AGX / LB9MG

Amateur radio and embedded systems

Disk space monitoring & e-mail notifications with Bash

Running out of disk space is a common problem for unattended Linux boxes like database servers or backup storage servers. Usually I would use Zabbix (or Nagios) do to the monitoring but it would be an overkill for a Raspberry Pi or a single NAS so I made a small Bash script. This script runs df, checks disk usage and sends mail in case the free space is running low.

First of all the mail command must be configured properly in the system. I recommend installing ssmtp to handle outgoing mail. There are many tutorials on configuring ssmtp (a working SMTP account somewhere is also needed).

Configuration options at the beginning of the script are self-explanatory. The ignore option is helpful for mountpoints like CD drives (that always appear full). It won't work for the / mountpoint due to the way the name is matched against the ignore list.

The script can be run every couple of hours from cron. It should not be run too often, because it will send mail every time it is executed if disk usage is too high. :)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#!/bin/bash
# --------- configuration ---------
WARNING_PERCENTAGE=91
IGNORE_MOUNTPOINTS="/mnt/cdrom" #does not work for / mountpoint, eg. "/mnt/cdrom"
MAIL_TO="ticket@yourdomain.com"
MAIL_FROM="disk_usage@yourdomain.com"
# ---------------------------------

HOSTNAME=`hostname`
MAIL_SUBJECT="low disk space on $HOSTNAME"

MAIL_BODY=""
SEND_WARNING=0
L=`df | grep '/' | awk '{printf ("%s %i\n",$6, $3*100 / $2); }'`

while read -r line; do
    arr=($line)
    mountpoint=${arr[0]}
    percentage_used=${arr[1]}
    echo "$mountpoint usage $percentage_used%"

    #filter mountpoints to be ignored
    if [[ $IGNORE_MOUNTPOINTS =~ .*$mountpoint*. ]]; then
        if [[ $mountpoint != "/" ]]; then   #workaround for / mountpoint
            echo "ignoring $mountpoint" #it would match against any possible path
            continue
        fi
    fi

    if [ "$percentage_used" -gt $WARNING_PERCENTAGE ]; then
        MAIL_BODY="$MAIL_BODY $HOSTNAME mountpoint $mountpoint disk usage too high $percentage_used %, "
        SEND_WARNING=1
    fi
done <<< "$L"

if [ $SEND_WARNING -eq 1 ]; then
    echo $MAIL_SUBJECT
    echo $MAIL_BODY
    echo $MAIL_BODY | mail -aFrom:$MAIL_FROM -s "$MAIL_SUBJECT" -t $MAIL_TO
fi