#! /bin/sh # -*- tcl -*- make next line a commnet in tcl \ exec wish -f $0 -- ${1+"$@"} # DFW -- Disk Free-space Watcher # Written in Tcl/Tk, portable across all major OS platforms # # @Author: Tong SUN, (c)2003-2006, all right reserved # @Version: $Date: 2006/05/22 17:36:42 $ $Revision: 1.4 $ # @Home URL: http://xpt.sourceforge.net/ # First draft: Laurent Duperval, (c)2000 # #{{{ LICENSE: # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, provided # that the above copyright notices appear in all copies and that both those # copyright notices and this permission notice appear in supporting # documentation, and that the names of author not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. Tong Sun makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # TONG SUN DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ADOBE # SYSTEMS INCORPORATED AND DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY # SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER # RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #}}} # # Support free software movement! Please send you comments, suggestions, # bug reports, patches to the author via the xpt project Open Discussion # Forum. They are warmly welcome. Thank you for using the tools from the # xpt project. # # ============================================================== &cs === # .................................... Customizable Constant setting ... set ::INTERVAL 300000; # 5min # DFW threshold levels, which the output colors based on. # Moreover, if the threshold is over ::DF_THRESHOLD_H, # you will be noticed every ::INTERVAL/1000 seconds if it # grows even more bigger than the previous figure. # Adjust the check interval accordingly if that annoys you. set ::DF_THRESHOLD_0 50 set ::DF_THRESHOLD_L 80 set ::DF_THRESHOLD_H 90 # ============================================================== &gv === # .................................................. Global Varibles ... set previousdisks 0 # ############################################################## &ss ### # ................................................ Subroutions start ... # =========================================================== &s-sub === proc getDf {ww} { global diskstat global previousstats global previousdisks disks global mountpoints global widget # update df values set mountpoints {} catch {unset diskstat} set output [exec {df}] foreach line [split $output \n] { if {[regexp {\S+\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)%\s+(\S+)} $line ->\ blocks used available percent mount] } { lappend mountpoints $mount set diskstat($mount,blocks) $blocks set diskstat($mount,available) $available set diskstat($mount,percent) $percent set diskstat($mount,used) $used } } set mountpoints [lsort -unique $mountpoints] set disks [llength $mountpoints] if {$disks != $previousdisks} { set previousdisks $disks updatePreviousStats # update widgets catch {destroy $ww} frame $ww pack $ww -side top set i 0 foreach idx $mountpoints { set widget($idx,label) $ww.label$i set widget($idx,percent) $ww.percent$i label $widget($idx,label) -text $idx -anchor w label $widget($idx,percent) -textvariable diskstat($idx,percent) -anchor w grid $widget($idx,label) $widget($idx,percent) incr i } } } # =========================================================== &s-sub === proc updatePreviousStats {} { global diskstat global previousstats foreach idx [array names diskstat] { set previousstats($idx) $diskstat($idx) } } proc updateStats {ww} { global diskstat global previousstats global mountpoints global widget getDf $ww foreach idx $mountpoints { if {$diskstat($idx,percent) >= $::DF_THRESHOLD_H} { $widget($idx,percent) configure -fg red if {$diskstat($idx,percent) > $previousstats($idx,percent)} { # if {$diskstat($idx,used) > $previousstats($idx,used)} #puts stderr "] $idx -> O:$previousstats($idx,percent), N:$diskstat($idx,percent) " tk_messageBox -title "\[dfw] Free Space Alert" -message \ "$idx is at $diskstat($idx,percent)\% full \ ($diskstat($idx,used)/$diskstat($idx,blocks))" } } elseif {$diskstat($idx,percent) >= $::DF_THRESHOLD_L} { $widget($idx,percent) configure -fg orange } elseif {$diskstat($idx,percent) <= $::DF_THRESHOLD_0} { $widget($idx,percent) configure -fg green3 } else { $widget($idx,percent) configure -fg black } } updatePreviousStats update after $::INTERVAL updateStats $ww } # =========================================================== &s-sub === proc quit {} { foreach pending [after info] { #puts stderr "] x-cleaning: $pending"; after cancel $pending } exit } # ############################################################ &main ### # -------------------------------------------------------------- &is --- # ............................................................. init ... wm withdraw . set ww .dfw toplevel $ww wm protocol $ww WM_DELETE_WINDOW quit # -------------------------------------------------------------- &is --- # ........................................................ dfw frame ... set ww2 $ww.f frame $ww2 -relief sunken -borderwidth 2 pack $ww2 -side top -padx 8 -pady 10 -fill x set ww2 $ww2.diskstat # -------------------------------------------------------------- &is --- # ......................................................... controls ... button $ww.update -text "Update" -command "updateStats $ww2" button $ww.quit -text "Quit" -command quit spinbox $ww.s1 -from 0 -to 999 -width 3 -validate key \ -vcmd {string is integer %P} -command { set ::INTERVAL [expr [$ww.s1 get] * 60000] #puts stderr "] $::INTERVAL" } pack $ww.s1 $ww.update $ww.quit -side left # -------------------------------------------------------------- &is --- # ........................................................ launching ... $ww.s1 set [expr $::INTERVAL / 60000] getDf $ww2 updateStats $ww2 # ############################################################# &end ###