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.
Steps
=> 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
Output:
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 }'
Output:
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):
#!/bin/sh
df -H | grep -vE '^Filesystem|tmpfs|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 90 ]; then
echo "Running out of space \"$partition ($usep%)\" on $(hostname) as on $(date)" |
mail -s "Alert: Almost out of disk space $usep%" you@somewhere.com
fi
done
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.
#!/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
Featured Articles:
- 20 Linux System Monitoring Tools Every SysAdmin Should Know
- 20 Linux Server Hardening Security Tips
- Linux: 20 Iptables Examples For New SysAdmins

- My 10 UNIX Command Line Mistakes
- 25 PHP Security Best Practices For Sys Admins
- The Novice Guide To Buying A Linux Laptop
- Top 5 Email Client For Linux, Mac OS X, and Windows Users
- Top 20 OpenSSH Server Best Security Practices
- Top 10 Open Source Web-Based Project Management Software
Facebook it - Tweet it - Print it -
We're here to help you make the most of sysadmin work. So, subscribe!


{ 39 comments… read them below or add one }
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.
example:
df -HlP
(P) = adds posix compliance to the output.
Errors that occured: df -H
/dev/mapper/volume00-pgvol
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.
Regards,
Per L
Per Lindahl,
Thanks for sharing your tip!
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
For my case:
df -h | grep d30 | awk ‘{ print $5 ” ” $1 }’ | while read output;
worked better. Thanks for shell script, life saver one.
HI
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
Regards
Sorabh harit
@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:
http://www.qwertyboy.org/files/diskspace.txt
Niek.
Can you please tell me how to find disk usage for a particular user only…!
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$ ./diskscript.sh
13% /dev/cciss/c0d0p2
17% /dev/cciss/c0d0p1
1% /dev/cciss/c0d0p5
./diskscript.sh: line 4: syntax error near unexpected token `do’
./diskscript.sh: line 4: `do’
#!/bin/sh
#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}’
do
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%” derek@iona.com
fi
done
while executing the below script i am getting the following:
Script:
#!/bin/sh
df -H | grep -vE ‘^Filesystem’ | 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%” Hari-Krishna.Reddy@in.standardchartered.com
fi
done
Error:
sh diskAlert.sh
/dev/mapper/rootvg-rootvol
diskAlert.sh: line 7: [: /dev/mapper/rootvg-rootvol: integer expression expected
/ 4.2G
diskAlert.sh: line 7: [: /: integer expression expected
14% /dev/sda1
0% none
/dev/mapper/rootvg-homevol
diskAlert.sh: line 7: [: /dev/mapper/rootvg-homevol: integer expression expected
/home 2.1G
diskAlert.sh: line 7: [: /home: integer expression expected
/dev/mapper/rootvg-sharedvol
diskAlert.sh: line 7: [: /dev/mapper/rootvg-sharedvol: integer expression expected
/shared 6.3G
diskAlert.sh: line 7: [: /shared: integer expression expected
/dev/mapper/rootvg-varvol
diskAlert.sh: line 7: [: /dev/mapper/rootvg-varvol: integer expression expected
/var 2.1G
diskAlert.sh: line 7: [: /var: integer expression expected
can any one help me on this.
i want the disk space scripts where it should send the mail in the .lst file
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
thnks
david
Can you send your crontab scripts?
Hi
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
Prasanna
I am using Gentoo and i get the following error:
./freespace.sh: 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
thansk
hello..
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?
Hi,
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.
Regards,
Neo
#!/bin/sh ADMIN="usuario@domain.com" ALERT1=95 ALERT2=80 ALERT3=70 # Exemplu: EXCLUDE_LIST="/dev/hdd1|/dev/hdc5" EXCLUDE_LIST="/dev/sr0" # #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: # 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 $ALERT1 ] ; then echo "Queda menos de `expr 100 - $usep` % en la particion: $partition del servidor ServerName, \ $(date +%d-%b-%Y)" | \ mail -s "Alerta alta prioridad: Informacion tamaño disco: $usep %" $ADMIN fi if [ $usep -ge $ALERT2 ] ; then echo "Queda menos de `expr 100 - $usep` % en la particion: $partition del servidor ServerName, \ $(date +%d-%b-%Y)" | \ mail -s "Alerta media prioridad: Informacion tamaño disco: $usep %" $ADMIN fi if [ $usep -ge $ALERT3 ] ; then # espacio= expr 100 - $ALERT3" echo "Queda menos de `expr 100 - $usep` % en la particion: $partition del servidor ServerName, \ $(date +%d-%b-%Y)" | \ mail -s "Alerta baja priridad: Informacion tamaño disco: $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 fisyntax 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
@@rebelteam
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
#!/usr/bin/bash
#admin email account
ADMIN="test@test.com"
# set usage alert threshold
THRESHOLD=10
#hostname
HOSTNAME=$(hostname)
#mail client
MAIL=/usr/bin/mail
# store all disk info here
EMAIL=""
for line in $(df -kh | egrep '^/dev/' | awk '{ print $6 "_:_" $5 }')
do
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" ];
then
EMAIL=”$(date): Running out of diskspace on $HOSTNAME\n”
EMAIL=”$EMAIL\n$part ($part_usage%) >= (Threshold = $THRESHOLD%)”
elif [ $part_usage -ge $THRESHOLD ];
then
EMAIL=”$EMAIL\n$part ($part_usage%) >= (Threshold = $THRESHOLD%)”
fi
The script doesn’t work when:
1) there is a filesystem with “$” (nfs mounted coming from windows hidden shares)
i.e //10.10.10.10/back$
2) the name of a filesystem is large and the percentage of use appears in another line
i.e.
//10.10.10.10/verylongnamefilesystem
78140128 45746488 32393640 59% /mnt/
Regards.
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 http://galinux.myftp.org/hdfree/
when I run script on solair 10. It errors
# ./Diskalert.sh
./Diskalert.sh: syntax error at line 21: `usep=$’ unexpected
Please help me?
Thank you very much
Best regards,
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?
None of the scripts here work on RHEL5.5.
All of them give errors….
hi,
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
@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
hi,
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.
Thanks..
Very nice, with some minor changes it works beautifully!!!
Thanks for helping out the coding-handicapped!
hi
iam getting the below for my shell script for space alert on linus server
/home/oracle/dba/scripts > ./space_alert.sh
./space_alert.sh: 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
#!/bin/bash
SENT_TO="dba-support@marlabs.com"
LOGFILE=/home/oracle/dba/scripts/log/disk_alert.log
ALERT=10
EXCLUDE_LIST="/dbbackup"
if [ -f ${LOGFILE} ]; then
rm $LOGFILE
fi
df -HP | grep -vE ‘^Filesystem|tmpfs|cdrom|product|mapper’ | awk ‘{ print $5 ” ” $6 }’ | while read output;
do
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
fi
echo “Running out of space on $partition ($usep%) on $(hostname) as on $(date)” >> ${LOGFILE}
echo “” >> ${LOGFILE}
fi
done
if [ -f ${LOGFILE} ]; then
/bin/mail -s “space_alert.sh – $(hostname) – Almost out of disk space” $SENT_TO < ${LOGFILE}
fi
#rm $LOGFILE
Please help on this
thanks
there are some issues with this script
- it won’t work with non english output from df
change
grep -vE "^Filesystem|tmpfs|cdrom"to
grep -vE "^Dateisystem|tmpfs|cdrom"or you could change it to
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
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
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
fi
fi
to remove non-local drives it would be better so use the “-l” option of df (substitute “df -H” with “df -lH”).
Please provide me rhe query for solaris and HP-UX and IBM-AIX
Very urgent please
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
OP- You rock. You saved my arse this time around…..
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.
Ok this is the slightly modified version, tested and working on different versions of linux …Enjoy!
#!/bin/bash
> alert.txt
HOST=$(hostname)
THRES=20
COUNT=1
df -HP | grep -vE ‘Filesystem|tmpfs’ | awk ‘{ print $5 ” ” $6 }’ |
while read space;
do
DISK=$(echo $space | cut -d “%” -f1)
DRIVENAME=$(echo $space | cut -d ” ” -f2)
if [ "$DISK" -ge "$THRES" ]
then
echo You have used “$DISK”% on drive “$DRIVENAME” on server “$HOST” >>alert.txt
fi
done
echo alert.txt | mail -s “Disk space Alert on server $HOST” root
This script is working fine
#!/bin/sh df -H | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{ print $5 " " $6 }' | while read output; do 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%" Someone@email.com 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%" amer.siddique@bskyb.com fi done