Shell script to watch the disk space and send an email - nixCraft

Shell script to watch the disk space and send an email

Shell script to watch the disk space and send an email alert
The df command under Linux displays the amount of disk space available on the file system containing each file name argument. Without any command-line argument, the df lists space available on all currently mounted Linux file systems. Let us see how to send an email alert when you run out of disk space by setting up 90% as the threshold.

Tutorial details
Difficulty level Easy
Root privileges Yes
Requirements Linux or Unix terminal
Category Disk Management
OS compatibility BSD Linux Unix
Est. reading time 4 minutes

Linux shell script to send an alert email if disk usage exceeds 90%

The steps are as follows:
(a) First, find disk space usage using the df command.
(b) Then filter out filesystem and find out the percentage of space using the grep command or egrep command.
(c) Write a shell script to watch the disk space and send an email.

Step # 1: First get disk space:

Open the terminal application and type the df command (no need to use the du command) to check free disk space on your Linux or Unix server. For example:
$ df -H
The -H option show sizes in powers of 1000 as follows:

Filesystem             Size   Used  Avail Use% Mounted on
/dev/hdb1               20G    14G   5.5G  71% /
tmpfs                  394M   4.1k   394M   1% /dev/shm
/dev/hdb5               29G    27G   654M  98% /nas/www

Step # 2: Next filter out filesystem and find out the percentage of space

We don’t want unwanted file systems. For example, NFS mounted or CD/DVD ROM or loopback devices. So how do you filter out the results? use the grep command or egerp command as follows:
$ df -H | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{ print $5 " " $1 }'
$ df -H | grep -vE '^Filesystem|tmpfs|cdrom|loop|udev' | awk '{ print $5 " " $1 }'

Now we get desired outputs with for disk usage in percentage as follows:

71% /dev/hdb1
98% /dev/hdb5

Let us break down the df -H | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{ print $5 " " $1 }' command:

  • First, you run the df command with the -H option to get a human-readable output on your screen.
  • Next, you use the grep command to filter out the lines that start with the following strings: Filesystem, tmpfs, and cdrom. In other words, you only need a real block disk/device and filter out the rest of the outputs.
  • Finally, you use the awk command to display the fifth and first columns of the output. The fifth column is the percentage of disk space used, and the first column is the mount point.
Prerequisite
By default, mail command may not be installed on your system. Hence, use the apk command on Alpine Linux, dnf command/yum command on RHEL & co, apt command/apt-get command on Debian, Ubuntu & co, zypper command on SUSE/OpenSUSE, pacman command on Arch Linux to install the mail.

Step # 3: Write a shell script

So far, so good. The above Linux command displays fields 5 and 1 of the df command. Now all you need to do is write a script to see if the percentage of space is >= 90%. In other words, the following shell script will send an alert email alert if disk usage exceeds 90%.

#!/bin/sh
# Purpose: Monitor Linux disk space and send an email alert to $ADMIN
ALERT=90 # alert level 
ADMIN="you@cyberciti-biz" # dev/sysadmin email ID
df -H | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{ print $5 " " $1 }' | while read -r output;
do
  echo "$output"
  usep=$(echo "$output" | awk '{ print $1}' | cut -d'%' -f1 )
  partition=$(echo "$output" | awk '{ print $2 }' )
  if [ $usep -ge $ALERT ]; then
    echo "Running out of space \"$partition ($usep%)\" on $(hostname) as on $(date)" |
    mail -s "Alert: Almost out of disk space $usep%" "$ADMIN"
  fi
done
Here is how to install the mail command on a Debian/Ubuntu Linux using the apt-get command or apt command:
$ sudo apt install mailutils
For RHEL/CentOS/Rocky/Oracle/Alma or Fedora Linux try the yum command or dnf command to install the mail command:
$ sudo dnf install mailx
Make sure your system can route outgoing email. You can route (send) email using Gmail account with help of msmtp or ssmtp.

Step # 4: Setup a Cron job

Save and install the script using a cronjob. Copy script to /etc/cron.daily/ using the cp command (script downolad link):
# cp diskAlert /etc/cron.daily/
Set up permission using the chmod command. For example:
# chmod +x /etc/cron.daily/diskAlert
Once placed in the /etc/cron.daily/ directory, the diskAlert script will run daily on Linux systems. This ensures that important maintenance tasks, like monitoring disk space, are performed regularly by the sysadmin, preventing any potential issues. That’s all there is to it.

Installing cron job

Of course, you install it as cronjob using the crontab command too. For example, this is useful when you do not wish to use the /etc/cron.daily/ directory:
$ crontab -e
Write cronjob as per your requirement. For example:
10 0 * * * /path/to/diskAlert
OR
@daily /path/to/diskAlert

An updated script version to watch the disk space and send email alert

Tony contributed and updated my script – You can exclude selected filesystem in case you don’t want monitor all filesystems.

#!/bin/sh
# set -x
# Shell script to monitor or watch the disk space
# It will send an email to $ADMIN, if the (free available) percentage of space is >= 90%.
# --------------------------------------------------------------------------------------------------------
# Set admin email so that you can get email.
ADMIN="root"
# set alert level 90% is default
ALERT=90
# Exclude list of unwanted monitoring, if several partions then use "|" to separate the partitions.
# An example: EXCLUDE_LIST="/dev/hdd1|/dev/hdc5"
EXCLUDE_LIST="/auto/ripper|loop"
#
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
#
main_prog() {
while read -r output;
do
  #echo "Working on $output ..."
  usep=$(echo "$output" | awk '{ print $1}' | cut -d'%' -f1)
  partition=$(echo "$output" | awk '{print $2}')
  if [ $usep -ge $ALERT ] ; then
     echo "Running out of space \"$partition ($usep%)\" on server $(hostname), $(date)" | \
     mail -s "Alert: Almost out of disk space $usep% on $partition" "$ADMIN"
  fi
done
}
 
if [ "$EXCLUDE_LIST" != "" ] ; then
  df -H | grep -vE "^Filesystem|tmpfs|cdrom|${EXCLUDE_LIST}" | awk '{print $5 " " $6}' | main_prog
else
  df -H | grep -vE "^Filesystem|tmpfs|cdrom" | awk '{print $5 " " $6}' | main_prog
fi

Summing up

I hope this quick Linux and Unix post and script helps someone to monitor their free disk space health and get an email alert before you run out of it. You can also send push notification to your iOS or Android phone using the same method. See the following tutorial for more info:

🥺 Was this helpful? Please add a comment to show your appreciation or feedback.

nixCrat Tux Pixel Penguin
Hi! 🤠
I'm Vivek Gite, and I write about Linux, macOS, Unix, IT, programming, infosec, and open source. Subscribe to my RSS feed or email newsletter for updates.

70 comments… add one
  • BG May 14, 2013 @ 23:37

    On Solaris try bash shell if you are having issue

    replace #!/bin/sh with #!/bin/bash

    Hope this helps!

  • viny Sep 26, 2013 @ 5:27

    I ran this script and found the error mentioned below:-

    #!/bin/sh
    df -H | grep -vE '^Filesystem|none|cdrom' | awk '{ print $5 " " $1 }' | while read output;
    do
      echo $output
      usep=$(echo $output | awk '{ print $1}' | cut -d'%' -f1  )
      partition=$(echo $output | awk '{ print $2 }' )
      if [ $usep -ge 50 ]; then
        echo "Running out of space "$partition ($usep%)" on $(hostname) as on $(date)" |
         mail -s "Alert: Almost out of disk space $usep%" x@gmail.com
      fi
    done
    

    Error:-
    ./abc2.sh: syntax error at line 5: `usep=$’ unexpected

  • swaraj Sep 26, 2013 @ 16:49

    Strange…!!
    Which Shell are you using..??
    sorry no correct answers from me…
    just copy pasted and it worked fine for me(using bash) 🙂

  • swaraj Sep 26, 2013 @ 16:57

    Hi again,,
    wild guess try
    #!/bin/bash
    or
    /usr/xpg4/bin/sh

    Good luck

  • Kyle Nov 3, 2014 @ 19:13

    What is the function of ‘usep’ and where can I find an rpm for it?

  • harish sharma Nov 11, 2014 @ 6:46

    ou are a given an input file serverList.txt and simulated input of disk utilization diskout.txt. You are expected to write an automated script which would have the serverList.txt as input which has the list of IP Addresses of the servers and the simulated output of the disk utilization file diskout.txt as the input file.

    The script should process these files and find the IP Addresses which breaches the threshold of 70%.

  • Menno Nov 11, 2015 @ 11:38

    Love it! Thanks 🙂

  • PK Nov 28, 2017 @ 19:22

    On below script, how can i set up different threshold for different file system. Need help.

    #!/bin/sh
    # set -x
    # Shell script to monitor or watch the disk space
    # It will send an email to $ADMIN, if the (free available) percentage of space is >= 90%.
    # -------------------------------------------------------------------------
    # Set admin email so that you can get email.
    ADMIN="root"
    # set alert level 90% is default
    ALERT=90
    # Exclude list of unwanted monitoring, if several partions then use "|" to separate the partitions.
    # An example: EXCLUDE_LIST="/dev/hdd1|/dev/hdc5"
    EXCLUDE_LIST="/auto/ripper"
    #
    #::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    #
    function main_prog() {
    while read output;
    do
    #echo $output
      usep=$(echo $output | awk '{ print $1}' | cut -d'%' -f1)
      partition=$(echo $output | awk '{print $2}')
      if [ $usep -ge $ALERT ] ; then
         echo "Running out of space \"$partition ($usep%)\" on server $(hostname), $(date)" | \
         mail -s "Alert: Almost out of disk space $usep%" $ADMIN
      fi
    done
    }
    
    if [ "$EXCLUDE_LIST" != "" ] ; then
      df -H | grep -vE "^Filesystem|tmpfs|cdrom|${EXCLUDE_LIST}" | awk '{print $5 " " $6}' | main_prog
    else
      df -H | grep -vE "^Filesystem|tmpfs|cdrom" | awk '{print $5 " " $6}' | main_prog
    fi
    
  • aref Apr 17, 2021 @ 5:04

    Thanks for Sharing

  • Anonymous Apr 13, 2022 @ 23:35

    Great job

  • Amaterasu Aug 22, 2022 @ 6:47

    Awesome script especially updated version.

  • Pras Nov 2, 2022 @ 11:27

    what if i want to know which file has caused a spike in usage?

  • Jakob Ward Feb 28, 2023 @ 20:26

    Just what I needed for my LINUX disk space alerts! Thank you.

  • Alan Robertson Apr 6, 2023 @ 19:54

    Very helpful – thanks. I found I didn’t have mail installed on my Debian machine and wanted to use an external SMTP provider anyway, so install msmtp instead. I changed the mail command to the following:

    printf "Subject: Disk space warning\n\nAlert: Almost out of disk space on server - $usep%% used" | msmtp -d -a default "$ADMIN"
    
  • Mike May 2, 2024 @ 1:27

    I made a little bit change to take the disk space information and send out 1 mail. I try to put it in cron job. but it only sent out 1 blank mail to me. please help.

    #!/bin/sh
    ADMIN="admin@email.com"
    TO="myself@email.com"
    EXCLUDE_LIST="/dev/sda2"
    
    main_prog() {
    while read -r output;
    do
      #echo "Working on $output ..."
      usep=$(echo "$output" | awk '{ print $1}' | cut -d'%' -f1)
      partition=$(echo "$output" | awk '{print $2}')
      msgs+=$(echo -e "--- Running space \"$partition ($usep%)\" on server $(hostname) .\r\n")
    done
    echo $msgs | mail -s "Disk Space on Server $(hostname)" $TO -aFrom:$ADMIN
    }
    
    if [ "$EXCLUDE_LIST" != "" ] ; then
      df -H | grep -vE "^Filesystem|tmpfs|cdrom|${EXCLUDE_LIST}" | awk '{print $5 " " $6}' | main_prog
    else
      df -H | grep -vE "^Filesystem|tmpfs|cdrom" | awk '{print $5 " " $6}' | main_prog
    fi
    
    • 🛡️ Vivek Gite (Author and Admin) Vivek Gite May 4, 2024 @ 1:04

      In #/bin/sh the += is undefined. Similarly echo flags are undefined, too in #/bin/sh. Try using #!/bin/bash and the line should be:

      echo "$msgs" | mail -s "Disk Space on Server $(hostname)" $TO -aFrom:$ADMIN

Leave a Reply

Your email address will not be published. Required fields are marked *

Use HTML <pre>...</pre> for code samples. Your comment will appear only after approval by the site admin.