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 /
OR
# 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'
15
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
#!/bin/bash # Tested Under FreeBSD and OS X FS="/usr" THRESHOLD=90 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
#!/bin/bash # Tested Under FreeBSD and OS X FS="/usr" THRESHOLD=90 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"
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
🐧 Get the latest tutorials on Linux, Open Source & DevOps via:
- RSS feed or Weekly email newsletter
- Share on Twitter • Facebook • 28 comments... add one ↓
Category | List of Unix and Linux commands |
---|---|
File Management | cat |
Firewall | Alpine Awall • CentOS 8 • OpenSUSE • RHEL 8 • Ubuntu 16.04 • Ubuntu 18.04 • Ubuntu 20.04 |
Network Utilities | dig • host • ip • nmap |
OpenVPN | CentOS 7 • CentOS 8 • Debian 10 • Debian 8/9 • Ubuntu 18.04 • Ubuntu 20.04 |
Package Manager | apk • apt |
Processes Management | bg • chroot • cron • disown • fg • jobs • killall • kill • pidof • pstree • pwdx • time |
Searching | grep • whereis • which |
User Information | groups • id • lastcomm • last • lid/libuser-lid • logname • members • users • whoami • who • w |
WireGuard VPN | Alpine • CentOS 8 • Debian 10 • Firewall • Ubuntu 20.04 |
I think Linux desktop lack alarm in notification area about disks getting full just like you do in M$
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”
to
/usr/bin/zenity –notification –text=”The disk $FS ($CURRENT% used) is almost full. Delete some files or add a new disk.”
good one, though i use nagios, great tool.
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.
YMMV.
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.
I think zenity (for Gnome) or kdialog (KDE) could be used to pop-up an info box, instead (or additionally) to sending an email.
@petrescs,
The FAQ has been updated.
COOOOOl!!!
I was unaware of zenity. Very sweet.
Jaysunn
Hello,
I tried to use this script in my Ubuntu.
First,
# 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.
@Carmen: there’s no /usr in your case, just / (that is, root)
Try df -P / | grep / | awk ‘{ print $5}’ | sed ‘s/%//g’ instead
Thank you!!
That was very useful.
Hello there,
Now when I change this to the following ( note the space between the “M” and the “H” in “/media/FREECOM HDD”:
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,
Jeroen
p.s. great website for shell programming and linux things !!!
This line should be corrected
HDD is not a valid mount point, use full path like /usr /home /www
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.
Thanks,
Jeroen
@Jeroen: have not tried this, but it can help you https://help.ubuntu.com/community/RenameUSBDrive
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
Hello,
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:
/media/FREECOM_HDD932
Is this something from Fedora 8 with crontab ??
This was my entry :
36 19 * * * /home/paula/shells/check_partitions_sizes.sh
Regards,
Jeroen
@Jeroen: Try add “DISPLAY=:0.0” (those are zero, not lowercase O, and no quotes) as first line in your user crontab.
You can get rid of sed like so:
echo “${output[11]/\%/}”
@Jeroen
You need to run it as follows /etc/profile.d/run.cron.gui.sh:
Set permissions:
Finally update your cronjob:
OR assuming that you are always on 0.0
HTH
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,
Jeroen
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
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.
Jeroen
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.
Thanks for the script, works great!
Hello,
I using this scripts and i am getting this following error
# vi full.ksh
“full.ksh” 7 lines, 377 characters
#!/bin/ksh
set -x
# Tested Under FreeBSD and OS X
FS=”/usr”
THRESHOLD=90
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
FS=/usr
THRESHOLD=90
full.ksh: syntax error at line 6: `OUTPUT=’ unexpected
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.
Use -P for POSIX standard:
$ df -P | awk ‘/\/home$/{ gsub(/%/,””); print $5 }’