#!/usr/bin/perl -w
use strict;
use warnings;
# globals
use vars qw/ $_TIMER /;
# auto-flush output; no buffering STDOUT
BEGIN { ++$| }
# try to get high-precision time reporting capability
$_TIMER = sub { time };
require Time::HiRes if eval {
require Time::HiRes;
$_TIMER = sub { &Time::HiRes::time };
1;
};
use File::Util;
use Class::OOorNO qw/ shave_opts /;
# initialize variables to use
my($dirs,$files,$exdirsizes,$dirsize,$fcount,$dcount) = (0,0,0,0,0,0);
# use current working directory if no directory name(s) provided
$ARGV[0] = '.' unless @ARGV;
# search for options/flags among input, check input for non-existent file names
for (my($i) = 0; $i < @ARGV; ++$i) {
if ($ARGV[$i] eq '-h' || $ARGV[$i] eq '--help') {
print &usage and exit
}
if ($ARGV[$i] eq '-e' || $ARGV[$i] eq '--exclude-dirs') {
splice(@ARGV,$i,1); $exdirsizes = 1;
# can't use "CORE::last" here because we need to make sure we've
# checked that every element in @ARGV is not '-h' or '--help'
}
elsif (!-e $ARGV[$i]) { die &nosuchfile($ARGV[$i]) }
}
my($f) = File::Util->new();
# calculate directory size
foreach (@ARGV) {
print <<__PROGRESS__;
Collecting disk usage information for "$_" ...
__PROGRESS__
my($dir) = $_;
foreach ($f->list_dir($dir,qw/
--with-paths
--no-fsdots
--follow
--max-dives=100000000 /)
) {
next unless defined -s $_; # don't know why this is neccessary, but is
if (-d $_) {
++$dcount;
$dirsize += -s $_ unless $exdirsizes
}
else {
++$fcount;
$dirsize += -s $_
}
}
}
# print out findings and exit
print &summary() and exit;
# subroutine to display summary of findings
sub summary { <<__SUMMARY__ }
$dirsize bytes in $fcount files and $dcount directories.
that's ${\ sprintf('%0.2f', $dirsize / 1024) } Kilobytes
${\ sprintf('%0.2f', $dirsize / 1048576) } Megabytes
${\ sprintf('%0.3f', $dirsize / 1073741824) } Gigabytes
${\ sprintf('%0.3f', $dirsize / 1099511627776) } Terabytes
calculated in ${\ sprintf('%0.2f', (&$_TIMER - $^T)) } seconds
__SUMMARY__
# subroutine to detail program usage
sub usage { <<__USAGE__ }
dirsize, gets the collective disk usage for the contents of a given
directory or list of directories. Version 1.0.0, 3-Dec-2003.
usage: dirsize [options] [list of directory names]
-h --help print this message
-e --exclude-dirs excludes file sizes of the actual directory
files that are encountered. (eg- typically
1024 bytes on linux file systems, and reported
as 0 bytes on Micro\044oft file systems)
-y --follow-symlinks follow symlinks
^^^
!!! Not yet implemented!
-f --one-fs stay on one filesystem; don't span partitions or
other storage devices
^^^
!!! Not yet implemented!
If no file names are given, dirsize will assume '.' as the directory for
disk usage reports.
__USAGE__
# subroutine to report non-existent file errors
sub nosuchfile { <<__NOSUCH__ }
No such file or directory "$_[0]"
__NOSUCH__
__END__
1 Kilobyte = 1,024 bytes
1 Megabyte = 1,048,576 bytes
1 Gigabyte = 1,073,741,824 bytes
1 Terabyte = 1,099,511,627,776 bytes