Shell script to watch the disk space

df displays the amount of disk space available on the file system containing each file name argument. If no file name is given, the space available on all currently mounted file systems is shown. Read man page of df if you are new to df command.


=> Find disk space using df

=> Filter out filesystem and find out the percentage of space using grep

=> Write a shell script

Step # 1: First get disk space:

$ df -H


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

$ df -H | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{ print $5 " " $1 }'


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

Step # 3: Write a shell script

Above command displays field 5 and 1 of df command. Now all you need to do is write a script to see if the percentage of space is >= 90% (download script):

df -H | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{ print $5 " " $1 }' | while read output;
  echo $output
  usep=$(echo $output | awk '{ print $1}' | cut -d'%' -f1  )
  partition=$(echo $output | awk '{ print $2 }' )
  if [ $usep -ge 90 ]; then
    echo "Running out of space \"$partition ($usep%)\" on $(hostname) as on $(date)" |
     mail -s "Alert: Almost out of disk space $usep%"

Setup Cron job

Save and install script as cronjob. Copy script to /etc/cron.daily/ (script downolad link)
# cp diskAlert /etc/cron.daily/
# chmod +x /etc/cron.daily/diskAlert

OR install as cronjob:
crontab -e

Write cronjob as per your requirement
10 0 * * * /path/to/diskAlert

Updated script version

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

# 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.
# set alert level 90% is default
# Exclude list of unwanted monitoring, if several partions then use "|" to separate the partitions.
# An example: EXCLUDE_LIST="/dev/hdd1|/dev/hdc5"
function main_prog() {
while read output;
#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

if [ "$EXCLUDE_LIST" != "" ] ; then
  df -H | grep -vE "^Filesystem|tmpfs|cdrom|${EXCLUDE_LIST}" | awk '{print $5 " " $6}' | main_prog
  df -H | grep -vE "^Filesystem|tmpfs|cdrom" | awk '{print $5 " " $6}' | main_prog

🐧 Get the latest tutorials on Linux, Open Source & DevOps via RSS feed or Weekly email newsletter.

🐧 60 comments so far... add one
CategoryList of Unix and Linux commands
Disk space analyzersncdu pydf
File Managementcat
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network UtilitiesNetHogs dig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04
60 comments… add one
  • Per Lindahl Mar 29, 2007 @ 15:16

    I noticed that on devices that have very long path in some cases there might be a line break appended to the output and that will in turn create an error when the script is run like:

    line 22: [: -ge: unary operator expected

    To remove the line break just append “-P” to the “df” command.

    df -HlP

    (P) = adds posix compliance to the output.

    Errors that occured: df -H
    50G 31G 19G 62% /localhome/postgresql

    with -P
    /dev/mapper/volume00-pgvol 50G 31G 19G 62% /localhome/postgresql

    Also if you only have one type of filesystem that you need to monitor then add “-t ext3” will only show EXT3 filesystems.

    Hope it helps.
    Per L

    • APV Jan 17, 2013 @ 8:55

      That really works.. Thank U 🙂

    • Gokhan Jun 17, 2014 @ 11:58

      I works, thank you.

    • granola Jan 26, 2015 @ 13:41

      Thanks, it actually enhances this script readability, also. 😉

  • 🐧 nixCraft Mar 30, 2007 @ 17:27

    Per Lindahl,

    Thanks for sharing your tip!

  • Trula May 6, 2007 @ 23:18

    Please show me if I need to get disk file last week or 10 days ago, what do I need to do?
    Thank you ~ Trula

  • Mehmet Buyukozer May 19, 2007 @ 23:55

    For my case:

    df -h | grep d30 | awk ‘{ print $5 ” ” $1 }’ | while read output;

    worked better. Thanks for shell script, life saver one.

    • d30 is the filename? Mar 9, 2017 @ 10:06

      i have a doubt regarding where can I put the filesystem path

  • sorabh harit Jul 10, 2007 @ 5:48


    thanks for script but i am getting following error
    on my solaris 9 servrer after executing the scipt.

    syntax error at line 5: `usep=$’ unexpected


    Sorabh harit

  • Niek Aug 17, 2007 @ 16:08

    @sorabh harit:
    That is because you run a “real” Bourne shell, which doesn’t understand the syntax on that line.

    Also, there is a fair bit of double code at the end, and use of a function isn’t really necessary.

    I’ve put up a modified version on my site:


  • Rohan Sep 13, 2007 @ 12:27

    Can you please tell me how to find disk usage for a particular user only…!

  • Derek Murphy Nov 14, 2007 @ 19:52

    I tried using this script but I’m getting a syntax error, trying to run this on linux(redhat as 4) any thoughts?

    -bash-3.00$ ./
    13% /dev/cciss/c0d0p2
    17% /dev/cciss/c0d0p1
    1% /dev/cciss/c0d0p5
    ./ line 4: syntax error near unexpected token `do’
    ./ line 4: `do’

    #df -H | grep -vE ‘^Filesystem|tmpfs|cdrom’ | awk ‘{ print $5 ” ” $1 }’ | while read output;
    df -F ext3 -k | grep -vE ‘^Filesystem|tmpfs|cdrom’ | awk ‘{print $5 ” ” $1}’
    echo $output
    usep=$(echo $output | awk ‘{ print $1}’ | cut -d’%’ -f1 )
    partition=$(echo $output | awk ‘{ print $2 }’ )
    if [ $usep -ge 90 ]; then
    echo “Running out of space “$partition ($usep%)” on $(hostname) as on $(date)” |
    mail -s “Alert: Almost out of disk space $usep%”

  • Hari Dec 2, 2007 @ 19:10

    while executing the below script i am getting the following:


    df -H | grep -vE ‘^Filesystem’ | awk ‘{ print $5 ” ” $1 }’ | while read output;
    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%”


    /dev/mapper/rootvg-rootvol line 7: [: /dev/mapper/rootvg-rootvol: integer expression expected
    / 4.2G line 7: [: /: integer expression expected
    14% /dev/sda1
    0% none
    /dev/mapper/rootvg-homevol line 7: [: /dev/mapper/rootvg-homevol: integer expression expected
    /home 2.1G line 7: [: /home: integer expression expected
    /dev/mapper/rootvg-sharedvol line 7: [: /dev/mapper/rootvg-sharedvol: integer expression expected
    /shared 6.3G line 7: [: /shared: integer expression expected
    /dev/mapper/rootvg-varvol line 7: [: /dev/mapper/rootvg-varvol: integer expression expected
    /var 2.1G line 7: [: /var: integer expression expected

    can any one help me on this.

  • Ambika Jan 25, 2008 @ 11:16

    i want the disk space scripts where it should send the mail in the .lst file

  • david Jul 22, 2008 @ 5:08

    i am able to run the shell script properly but if i put it in a crontab its not working fine
    can anyone plz suggest me in this


  • jack Sep 1, 2008 @ 10:25

    Can you send your crontab scripts?

  • Prasanna Oct 8, 2008 @ 8:31


    I have to select 10% of the files from a 1 million records file at random. Could anyone help me with a shell script?
    thanks and regards

  • adgar marks Jan 21, 2009 @ 16:08

    I am using Gentoo and i get the following error:

    ./ line 25: [: Ben: integer expression expected

    Once i do “echo $output”, i get an empty line and i dont know what wasi suppose to expect from $output.

    I hope someone could help me a bit


  • jack May 5, 2009 @ 13:17


    what if your both partitions will run out of space? you will receive 2 mails. if you have more partitions, then you will receive more mails… how you do to receive all messages in one mail?

    • Susmitha Sep 2, 2016 @ 3:49

      I too have the same query. Expecting the answer please.

  • Neo Jun 12, 2009 @ 11:43


    I have typed in df -h, all my files were display. I have found that my log file is full, file name /lsx/log sitting at 100%, then I typed in the command du -akd |sort -rn | more to sort from big to small, I found that /fb was the biggest and tried to clean up with then command cat /dev/null > fb, but didn’t clean up any of the files. Please advice me how to clean up log files when full.


  • rebelteam Jul 12, 2009 @ 13:32


  • kiran Nov 12, 2009 @ 23:49

    syntax error at line 5: `usep=$’ unexpected

    Hi iam getting hte same error. And unable to acces your URL provided forthe updated code..Can you please help me insortiugn this

  • rocky Feb 9, 2010 @ 22:13


    I got error while running you script on Solaris 10 box , any idea

    -bash-3.00$ ./test
    ./test: line 24: [: :: integer expression expected
    ./test: line 29: [: :: integer expression expected
    ./test: line 24: [: :: integer expression expected
    ./test: line 29: [: :: integer expression expected


    #admin email account

    # set usage alert threshold


    #mail client

    # store all disk info here

    for line in $(df -kh | egrep ‘^/dev/’ | awk ‘{ print $6 “_:_” $5 }’)

    part=$(echo “$line” | awk -F”_:_” ‘{ print $1 }’)
    part_usage=$(echo “$line” | awk -F”_:_” ‘{ print $2 }’ | cut -d’%’ -f1 )

    if [ $part_usage -ge $THRESHOLD -a -z “$EMAIL” ];
    EMAIL=”$(date): Running out of diskspace on $HOSTNAMEn”
    EMAIL=”$EMAILn$part ($part_usage%) >= (Threshold = $THRESHOLD%)”

    elif [ $part_usage -ge $THRESHOLD ];
    EMAIL=”$EMAILn$part ($part_usage%) >= (Threshold = $THRESHOLD%)”

    • llattan May 14, 2010 @ 17:28

      The script doesn’t work when:

      1) there is a filesystem with “$” (nfs mounted coming from windows hidden shares)

      i.e //$

      2) the name of a filesystem is large and the percentage of use appears in another line

      78140128 45746488 32393640 59% /mnt/


  • Ramírez May 17, 2010 @ 14:42

    I’ve made my own bash script for watching free space. Its main feature is that it runs with X and uses pop-ups for warning the user. Please see

  • victor Aug 12, 2010 @ 9:09

    when I run script on solair 10. It errors
    # ./
    ./ syntax error at line 21: `usep=$’ unexpected

    Please help me?
    Thank you very much

    Best regards,

  • broxigar Aug 18, 2010 @ 13:06

    When I try to run the updated script, on a Ubuntu server, I get an syntax error: “(” unexpected at “function main_prog() {”

    What is wrong here?

  • Brad Nov 1, 2010 @ 18:24

    None of the scripts here work on RHEL5.5.

    All of them give errors….

  • Rajesh Thakur Nov 11, 2010 @ 9:54

    i have multiple servers and i am running this script from single server where ssh keys fro all servers are added…
    issue: when i run it it throws me multiple mails on the id i specified in the script, if i have 12 linux remote servers thn it will throw 12 mails…i want to get details in one mail..

    does anyone has idea abt it please….it will be agreat assistance.

    Best wishes,
    Rajesh Thakur

  • Evert Mouw Nov 18, 2010 @ 10:53

    @broxigar and others:

    The syntax error “syntax error: “(” unexpected at “function main_prog() {”” can be solved by using bash instead of sh as script interpreter. So, after the shebang, use /bin/bash or /usr/bin/bash

  • souvik Nov 18, 2010 @ 13:24


    the above scripts have been really helpful but can u give me a generalized way of extracting the necessary mount points in different servers. i am avoiding the way to hard code the mount point.


  • swarajsingh Mar 8, 2011 @ 14:27
    #! /bin/sh
    #echo "enter erver no gibe the serer names u want to checkthe space inside";
     echo "for server $a"
      ssh -q $a  "df -k /sbclocal";     #df -k /sbcloca--sbclocal is folder where we spaces r checked
    echo "               "
     echo "for server $b"
    ssh -q $b  "df -k /sbclocal";
    echo "            ";
     echo "for server $c"
      ssh -q $c  "df -k /sbclocal";
    echo "           ";
     echo "for server $d"
       ssh -q $d  "df -k /sbclocal";
    echo "                   ";
    echo "for server $e"
     ssh -q $e  "df -k /sbclocal";
  • charles Apr 1, 2011 @ 23:49

    Very nice, with some minor changes it works beautifully!!!
    Thanks for helping out the coding-handicapped!

    • Sri Apr 11, 2011 @ 20:31

      iam getting the below for my shell script for space alert on linus server
      /home/oracle/dba/scripts > ./
      ./ line 15: [: /dbbackup: integer expression expected

      after that i have user df -HP command to append it .. but iam not able to get the ouput through mail

      if [ -f ${LOGFILE} ]; then
      rm $LOGFILE

      df -HP | grep -vE ‘^Filesystem|tmpfs|cdrom|product|mapper’ | awk ‘{ print $5 ” ” $6 }’ | while read output;
      usep=$(echo $output | awk ‘{ print $1}’ | cut -d’%’ -f1 )
      partition=$(echo $output | awk ‘{ print $2 }’ )
      if [ $usep -ge $ALERT ]; then
      if [ ! -f ${LOGFILE} ]; then
      touch $LOGFILE
      echo “Running out of space on $partition ($usep%) on $(hostname) as on $(date)” >> ${LOGFILE}
      echo “” >> ${LOGFILE}

      if [ -f ${LOGFILE} ]; then
      /bin/mail -s “ – $(hostname) – Almost out of disk space” $SENT_TO < ${LOGFILE}

      #rm $LOGFILE

      Please help on this


  • hypersmil Apr 20, 2011 @ 9:41

    there are some issues with this script

    – it won’t work with non english output from df

    Dateisystem             Size   Used  Avail Use% Eingehängt auf
    /dev/sda1              9,9G   3,3G   6,1G  35% /
    none                    17G   213k    17G   1% /dev
    none                    17G      0    17G   0% /dev/shm
    none                    17G   103k    17G   1% /var/run
    none                    17G      0    17G   0% /var/lock
    none                   9,9G   3,3G   6,1G  35% /var/lib/ureadahead/debugfs
    /dev/sda2               64G    17G    48G  26% /usr/local
    /dev/md0               147G    43G   105G  29% /mnt
    /dev/sde1              400G   203G   198G  51% /mnt/usbdisk


        grep -vE "^Filesystem|tmpfs|cdrom"


        grep -vE "^Dateisystem|tmpfs|cdrom"

    or you could change it to

      grep -vE "^[^/]|tmpfs|cdrom"

    to remove all lines not starting with a / which would also remove mounted network shares (sshfs, nfs etc.)

    additionally you could change the df command to

      df -hP fuse.sshfs -x nfs

    to remove mounted network devices

    another problem arises from the use of “sh” instead of bash –
    it won’t work –
    change the first line to


    to improve the error reporting you could also add the hostname to the subject line

    mail -s "Alert: $(hostname) almost out of disk space $usep%" $ADMIN
  • Stefan Jun 8, 2011 @ 19:38

    One reason for “integer expression expected”-errors is that if “$usep” is empty the test fails. Just test if “$usep” is empty and do nothing if so:

    if [ ! “$usep” == “” ] ; then
    if [ $usep -ge $ALERT ] ; then
    echo “Running out of space “$partition ($usep%)” on server $(hostname), $(date)” |
    mail -s “Alert: $(hostname) almost out of disk space $usep%” $ADMIN

  • Stefan Jun 8, 2011 @ 20:00

    to remove non-local drives it would be better so use the “-l” option of df (substitute “df -H” with “df -lH”).

  • BABU Jun 17, 2011 @ 12:01

    Please provide me rhe query for solaris and HP-UX and IBM-AIX

    Very urgent please

  • Juan Nicolas Jul 8, 2011 @ 5:55

    Great script, very simple and works like a charm. i have a question tho, could someone help me to make this script to run a gzip command and monitor the pid in order to start another gzip after the first pid ends? Is it possible to do that, well, in scripts all is possible 🙂

    I need to run 2 gzips on differents directories but can’t run them at the same time since this will eat my cpu and the disk IO will be very high. I need to start one and then the other. Thanks in advance

  • romsieze Jul 28, 2011 @ 17:52

    OP- You rock. You saved my arse this time around…..

  • pk Aug 28, 2011 @ 16:07

    I need to know the the usage of particular filesystem on 10 days back. Is it possible to use two or more df option in single line? If yes then how can we use twp grep statement in single line? Thanks in advance !!

    I used below line:df -H | grep d30 | awk ‘{print $5 ” ” $1}’ | main_prog

    But it is not sending any email.

  • stainless Jan 8, 2012 @ 16:07

    Ok this is the slightly modified version, tested and working on different versions of linux …Enjoy!


    > alert.txt




    df -HP | grep -vE ‘Filesystem|tmpfs’ | awk ‘{ print $5 ” ” $6 }’ |
    while read space;


    DISK=$(echo $space | cut -d “%” -f1)
    DRIVENAME=$(echo $space | cut -d ” ” -f2)

    if [ “$DISK” -ge “$THRES” ]


    echo You have used “$DISK”% on drive “$DRIVENAME” on server “$HOST” >>alert.txt


    echo alert.txt | mail -s “Disk space Alert on server $HOST” root

    • Amer Siddique Jan 9, 2012 @ 11:35

      This script is working fine

      df -H | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{ print $5 " " $6 }' | while read output;
        echo $output
        usep=$(echo $output | awk '{ print $1}' | cut -d'%' -f1  )
        echo $usep
        partition=$(echo $output | awk '{ print $2 }' )
        if [ $usep -ge 90 ]; then
          echo "Running out of space "$partition ($usep%)" on $(hostname) as on $(date) :  $usep%" |
           mail -s "Alert: Critical Almost out of disk space $partition $usep%"  fi
       if [ $usep -ge 85 ]; then
          echo "Running out of space "$partition ($usep%)" on $(hostname) as on $(date) :  $usep%" |
           mail -s "Alert: Warning Almost out of disk space $partition $usep%"
      • Saini Feb 28, 2012 @ 9:52


        I need to write a script which finds a Filesystem which is 100% full and then removes the directoriess temp and cache by running the below commands:
        rm /export/home/dw_adm/Informatica/PowerCenter8.6.1/server/infa_shared/Cache/*
        rm /export/home/dw_adm/Informatica/PowerCenter8.6.1/server/infa_shared/Temp/*
        can u plz suggest how to do?


        • Saini Feb 28, 2012 @ 10:56

          I have prepared the below script to find the filesystem which is 100% full and then remove directories from the given path.But while running its giving an error like:syntax error at line 11: `FSU=$’ unexpected.
          Please let me know the issue in the script.


          ## This script is for deleting temp and cache files from filesystems on DR. Following will be executed:
          ## 1)The file srwaisobi001data/zsrwaisobietl01/home will be checked for size.
          ## 2)If the file is FULL ,mail will be triggered to admin team to delete temp and cache files.
          ## 3)All temp and cache files will be deleted from DR filesystems if the file is FULL.
          ## 4)The file will be checked for space.
          ## 5)After the issue is resolved,mail will be sent to the team.
          ## In case of failure this task can safely be marked as Completed for current run and investigated later.
          FSU=$(df -h|grep '/export/home'|awk '{ print $5}'|sed 's/%//g')
          echo $FSU
          if [ $FSU -eq 100 ]
          echo "File System is 100% used.Send email to Admin team "
          df -h /export/home >space.txt
          mailx -s " srwaisobi001data/zsrwaisobietl01/home is full." space.txt
          mailx -s " srwaisobi001data/zsrwaisobietl01/home is ok." <space.txt

          Last edited by Admin. Reason: <pre> tag added to the code.

      • Pranee[ Aug 27, 2012 @ 6:46

        this scrip is not working in Sun solaries i have error came grep:illegal option –E
        usage -hblcnsviw pattern using usr/bin

      • Render Web Solutions Jan 4, 2017 @ 13:44

        Hi I am getting error 17: Syntax error: “done” unexpected (expecting “fi”)

        Please advise

  • shaimaa Sep 4, 2012 @ 15:59


    df -H is not working on my server..should I replace it with df -k ?

  • vanitha K B Sep 7, 2012 @ 5:41

    am new to this unix and wanted to know the syntax to schedule a cronjob. i just need to convey a message on alternate days at 10AM. i have a script with that message…

  • Leo Oct 16, 2012 @ 14:30

    For HP-UX: use bdf instead of df and mailx instead of mail

    bdf | grep '%' | awk '{ print $5 " " $6 }' | while read output;
      echo $output
      usep=$(echo $output | awk '{ print $1}' | cut -d'%' -f1  )
      partition=$(echo $output | awk '{ print $2 }' )
      if [ $usep -ge 90 ]; then
        echo "Running out of space "$partition ($usep%)" on $(hostname) as on $(date)" |
         mailx -s "Alert: Almost out of disk space $usep%"
  • Sitanshu Shekhar Oct 30, 2012 @ 14:04

    I want to run the Script (Contrubted by Tony) for watching the Disk space of multiple servers using SSH login.

    Can you please advice how can I do so?

    Thanks in advance.


  • 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:-

    df -H | grep -vE '^Filesystem|none|cdrom' | awk '{ print $5 " " $1 }' | while read output;
      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%"

    ./ syntax error at line 5: `usep=$’ unexpected

  • swaraj Sep 26, 2013 @ 16:49

    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

    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.


Leave a Reply

Your email address will not be published.

Use HTML <pre>...</pre> for code samples. Still have questions? Post it on our forum