This is a relatively common request. Someone wants, for one reason or another, to determine how much diskspace is currently in use.

While on Unix one could say "exec /bin/du" , that doesn't do well for a cross platform solution.

Here's an attempt to provide some Tcl code to do this. However, I'm uncertain whether the calculation is correct. Perhaps some of my fellow Tcl'ers can look in here and determine whether my algorithm is correct.


 #! /usr/tcl84/bin/tclsh8.4
 # Name: du.tcl
 # Purpose: 
 # Given a directory, calcuate the number of bytes of plain files within
 # the directory
 # Author: [email protected]
 # Date: Sept. 26, 2002
 # Version: 1.0

 package require log 

 log::lvChannel debug stderr

 proc dirsize {directory} {
        if { [file exists $directory ] == 0 } {
                return 0
        }
        if { [file readable $directory ] == 0 } {
                return 0
        }
        set size 0
        set noaccess {}
        foreach element [glob -nocomplain -directory $directory -types f *] {
                set path [file join $directory $element]
                if { [file readable $path] } {
                        array unset stats
                        file stat $path stats
                        incr size $stats(size)
                } else {
                        lappend noaccess $path
                }
        }
        if { [llength $noaccess] != 0 } {
                log::log debug $noaccess
        }
        return $size
 }

 proc dir_totalsize {directory} {
        if { [file exists $directory ] == 0 } {
                return 0
        }
        if { [file readable $directory ] == 0 } {
                return 0
        }

        set size 0
        set noaccess {}
        foreach element [glob -nocomplain -directory $directory -types d *] {
                set path [file join $directory $element]
                if { [file readable $path] } {
                        incr size [dirsize $element]
                } else {
                        lappend noaccess $path
                }
        }
        if { [llength $noaccess] != 0 } {
                log::log debug $noaccess
        }
        return $size
 } 

 # Test out implementation

 if { [file exists /tmp/small] == 0 } {
        exec mkdir /tmp/small
        exec cp /etc/motd /tmp/small/motd
 }

 puts [format "Size of /tmp/small is %d" [dirsize /tmp/small] ]
 puts [format "Size of %s is %d" $env(HOME) [dirsize $env(HOME)] ]
 puts [format "Size of /not/present is %d" [dirsize /not/present] ]
 puts [format "Total size of %s is %d" $env(HOME) [dir_totalsize $env(HOME)] ]

Well, please forgive me, I felt like writing a competeing version since this is something I needed too.

see du -PSE