≡ Menu

UNIX Get An Alert When Disk Is Full

I want to get an alert when my disk is full under UNIX and Mac OS X? How do I set a a specified threshold and run the script via cron?

The df command report file system disk space usage including the amount of disk space available on the file system containing each file name argument. Disk space is shown in 1K blocks by default, unless the environment variable POSIXLY_CORRECT is set, in which case 512-byte blocks are used.

Use df command and pass the -P option which make df output POSIX compliant (i.e. 512-byte blocks rather than the default. Note that this overrides the BLOCKSIZE specification from the environment).
# df -P /
# df -P /usr
Sample Outputs:

Filesystem    512-blocks     Used     Avail Capacity  Mounted on
/dev/aacd0s1e  162491344 21988048 127503992    15%    /usr

You can now simply grep /usr file system and print out used capacity:
# df -P /usr | grep /usr | awk '{ print $5}' | sed 's/%//g'
Or assign value to a variable:
# output=$(df -P /usr | grep /usr | awk '{ print $5}' | sed 's/%//g')
# echo $output

Under BASH or KornShell you can use arrays indexed by a numerical expression to make code small:
# output=($(df -P /))
# echo "${output[11]}"

A Sample Shell Script

# Tested Under FreeBSD and OS X
OUTPUT=($(LC_ALL=C df -P ${FS}))
CURRENT=$(echo ${OUTPUT[11]} | sed 's/%//')
[ $CURRENT -gt $THRESHOLD ] && echo "$FS file system usage $CURRENT" | mail -s "$FS file system" you@example.com

You need to modify syntax, if you are using KSH or TCSH / CSH instead of BASH. Save this script and run as a cron job:
@daily /path/to/your.df.script.sh

GUI Notification

Display warning dialog using /usr/bin/zenity

# Tested Under FreeBSD and OS X
OUTPUT=($(LC_ALL=C df -P ${FS}))
CURRENT=$(echo ${OUTPUT[11]} | sed 's/%//')
[ $CURRENT -gt $THRESHOLD ] && /usr/bin/zenity  --warning  --text="The disk $FS ($CURRENT% used) is almost full. Delete some files or add a new disk." --title="df Warning"
DF GUI Warning Notification

DF GUI Warning Notification

Finally update your cronjob as follows (you need to use DISPLAY variable to display output window):

36 19 * * *  DISPLAY=:0.0 /path/to/script.sh
Tweet itFacebook itGoogle+ itPDF itFound an error/typo on this page?

{ 28 comments… add one }

  • Dariusz21p August 13, 2009, 10:18 am

    I think Linux desktop lack alarm in notification area about disks getting full just like you do in M$

    • manvstech November 29, 2011, 10:07 pm

      Easy fix, change the last line of the script from:
      /usr/bin/zenity –warning –text=”The disk $FS ($CURRENT% used) is almost full. Delete some files or add a new disk.” –title=”df Warning”
      /usr/bin/zenity –notification –text=”The disk $FS ($CURRENT% used) is almost full. Delete some files or add a new disk.”

  • Shoaibi August 13, 2009, 10:35 am

    good one, though i use nagios, great tool.

    • nixCraft August 13, 2009, 10:51 am

      nagios is good if you’ve large number of servers or workstation. For a single laptop, desktop or a small number of server script will save the time.


  • Vitor Castro August 13, 2009, 11:26 am

    Vivtek he’s right!

    Nagios only make sense when you have a LAN.

    That ‘s a good idea use that script but you can also send the output to the STDOUT with some blink text, for example.

    I did something like that a few years ago.

  • petrescs August 13, 2009, 1:35 pm

    I think zenity (for Gnome) or kdialog (KDE) could be used to pop-up an info box, instead (or additionally) to sending an email.

  • nixCraft August 13, 2009, 1:44 pm


    The FAQ has been updated.

  • Jaysunn August 13, 2009, 3:54 pm


    I was unaware of zenity. Very sweet.


  • Carmen August 13, 2009, 5:27 pm

    I tried to use this script in my Ubuntu.
    # df -P /usr

    S.ficheros Bloques de 1024 Usado Libre Ocupado Montado en

    /dev/sda4 12399800 9341132 2433740 80% /

    # df -P /usr | grep /usr | awk ‘{ print $5}’ | sed ‘s/%//g’
    no answer…, and I was waiting for an output: 80
    What is wrong with that?

    Thanks in advance, I’m learning from you how to make scripts.

  • petrescs August 13, 2009, 5:53 pm

    @Carmen: there’s no /usr in your case, just / (that is, root)
    Try df -P / | grep / | awk ‘{ print $5}’ | sed ‘s/%//g’ instead

  • Carmen August 13, 2009, 7:13 pm

    Thank you!!
    That was very useful.

  • Jeroen August 14, 2009, 2:07 pm

    Hello there,

    Now when I change this to the following ( note the space between the “M” and the “H” in “/media/FREECOM HDD”:

    # Tested Under FreeBSD and OS X
    # File systems ( partitions )
    FSfreecomhdd="/media/FREECOM HDD"
    # Everything above 85 will be given a yellow card for warning
    # Check given file systems for size
    for FS in $FSfreecomhdd ; do
    	echo $FS
    	OUTPUT=($(LC_ALL=C df -P $FS))
    	CURRENT=$(echo ${OUTPUT[11]} | sed 's/%//')
    	[ $CURRENT -gt $THRESHOLD ] && /usr/bin/zenity  --warning  --text="The disk ${OUTPUT[12]} ($CURRENT% used) is almost full. Delete some files." --title="df Warning"

    it does not work anymore.

    Output will be :
    df: `/media/FREECOM’: No such file or directory
    df: no file systems processed
    ./check_partitions_sizes_simple.sh: line 15: [: -gt: unary operator expected
    df: `HDD’: No such file or directory
    df: no file systems processed
    ./check_partitions_sizes_simple.sh: line 15: [: -gt: unary operator expected

    With or without the escape character like FSfreecomhdd=”/media/FREECOM\ HDD” does not mather.

    The “df – P” will treat it as 2 strings which is obviously not my purpose.

    Is there another way to escape the space so that df will accept and treat this as 1 string in stead of 2 ??

    Thanks in advance,


    p.s. great website for shell programming and linux things !!!

  • nixCraft August 14, 2009, 2:37 pm

    This line should be corrected

    FSfreecomhdd="/media/FREECOM HDD"

    HDD is not a valid mount point, use full path like /usr /home /www

    FSfreecomhdd="/media/FREECOM / /home /www"
  • Jeroen August 14, 2009, 3:06 pm

    Hai Vivek

    Thanks for the quick response on my email. Yes this mount point is automatically made for the usb drive under Fedora 8 at rebooting time. I suppose the usb drive is FAT32 formatted and given as label this name. I will find a way to give the usb drive a correct name without the spaces. Then it will be mounted correctly at startup. I suppose another way is to mount this usb drive manually under /media/freecomhdd for example.



  • petrescs August 14, 2009, 3:16 pm

    @Jeroen: have not tried this, but it can help you https://help.ubuntu.com/community/RenameUSBDrive

  • Jeroen August 14, 2009, 3:50 pm

    Hey petrescs,

    Yes this is great. I was banging my head on this because I relabelled an usb disk before. But then there was no data on it so I put a fat filesystem on it with the correct label. This usb drive has lots of data on it so I am a little bit more carefull with it. I did not know Gnome was able to do this but I am just checking this out with gParted and I it did the job oke.

    Thanks, great call,


  • Jeroen August 14, 2009, 5:49 pm


    I used also the method of relabelling with mlabel and this works great and much faster then with gparted. I added an entry in the crontab but when this job runs it cannot display the warnings. I get this in the mail :
    (zenity:21175): Gtk-WARNING **: cannot open display:

    Is this something from Fedora 8 with crontab ??

    This was my entry :
    36 19 * * * /home/paula/shells/check_partitions_sizes.sh



  • petrescs August 14, 2009, 6:15 pm

    @Jeroen: Try add “DISPLAY=:0.0” (those are zero, not lowercase O, and no quotes) as first line in your user crontab.

  • Bash August 14, 2009, 6:55 pm

    You can get rid of sed like so:

    echo “${output[11]/\%/}”

  • nixCraft August 14, 2009, 7:41 pm


    You need to run it as follows /etc/profile.d/run.cron.gui.sh:

    # replace vivek with actual username, see xhost man page ;)
    /usr/bin/xhost +si:localuser:vivek

    Set permissions:

    chmod +x /etc/profile.d/run.cron.gui.sh

    Finally update your cronjob:

    36 19 * * *  DISPLAY=:0.0 /home/paula/shells/check_partitions_sizes.sh

    OR assuming that you are always on 0.0

    36 19 * * *  DISPLAY=:0.0 && /home/paula/shells/check_partitions_sizes.sh


  • Jeroen August 14, 2009, 8:35 pm

    Woooohhhhh, I just wanted to react on this response : petrescs 08.14.09 at 6:15 pm
    That was a great one and did the trick….

    Vivek : I will try this tomorrow….its getting late here…

    Thanks every one,


  • Shantanu Oak August 15, 2009, 6:00 am

    How about twittering the alert?
    # Twit the disk status alert away
    [ $CURRENT -gt $THRESHOLD ] && curl –basic –user username:password –data status=”$FS file system usage $CURRENT” http://twitter.com/statuses/update.xml

  • Jeroen August 15, 2009, 10:20 pm

    Hai Vivek and petrescs,

    The updating of the user cronjob worked fine so I changed my user crontab with the “DISPLAY=:0.0” . I am not sure what the extra value is of the /etc/profile.d/run.cron.gui.sh. With or without it my shell script starts and finishes and produces ( as far as I can see ) the same results.

    This “DISPLAY=:0.0” added to the cronjob solved for me other problems that output could not be showed on the display and gui applications could not be executed.

    Thank you @petrescs and @vivek for the answers to my questions. They were very helpful.


  • Mark Shields November 13, 2011, 5:37 pm

    No need to use grep and awk together, at least not in the context you’re using it. And sed is a bit of an overkill; use tr instead.

    df -P /usr | awk '/\/usr/{ printf $5}' | tr -d "%"
  • Randall Oveson March 6, 2012, 9:07 pm

    Thanks for the script, works great!

  • aj November 19, 2012, 3:16 pm

    I using this scripts and i am getting this following error

    # vi full.ksh
    “full.ksh” 7 lines, 377 characters
    set -x
    # Tested Under FreeBSD and OS X
    OUTPUT=($(LC_ALL=C df -P ${FS}))
    CURRENT=$(echo ${OUTPUT[11]} | sed ‘s/%//’)
    [ $CURRENT -gt $THRESHOLD ] && /usr/bin/zenity –warning –text=”The disk $FS ($CURRENT% used) is almost full. Delete some files or add a new disk.” — ti
    tle=”df Warning” | mail -s “$FS file system” ak@mountsaintvincent.edu

    # sh full.ksh
    full.ksh: syntax error at line 6: `OUTPUT=’ unexpected

  • Joe Bazin November 23, 2013, 9:01 pm

    I am looking for shell script which can be scheduled as cronjob under root to do the following on server named abcz on AIX platform.

    The script should capture the unsuccessful login attempts for user ID joebazin & oracle with the details -ip address, attempt time and number of attempts.

  • foobar October 28, 2014, 10:57 pm

    Use -P for POSIX standard:

    $ df -P | awk ‘/\/home$/{ gsub(/%/,””); print $5 }’

Leave a Comment