#!/opt/default/bin/perl # Netapps have snapshots, which cause a lot of problem for du and the output # from du is the snapshots + diskusage from user. This program excludes # snapshots by defaults from the diskusage output # options are # -k will cause du to express all block counts in terms of 1024 byte blocks # -s causes only the grand total of the names to be printed # -x excludes files/dirs matching to be excluded from # disk usage accounting. # written by: Rajeev Agrawala x7473 rajeeva@research.bell-labs.com # March 27, 1998 # March 30, 1998 # Added following options # # -a display all files # -l Compute diskusage for the same file system i.e don't descend dir if # file system changes # -r complain about dir/files which could not be opened. default is silent. # April 1, 1998 # Added following option # # -h display usage help use Getopt::Std; if (! getopts('ahklrsx:')) { &printusage(); exit(1); } if ($opt_h) { &printusage(); exit(0); } if (! @ARGV ) { @ARGV=("."); } if (! $opt_x) { $opt_x="^\.snapshot\$"; } foreach $entry (@ARGV) { undef (%inodes); undef $filesystem; next if ! -d $entry; next if ($opt_x && ($entry =~ /$opt_x/)); $total=&printdir($entry); if ($opt_s) { &printline($entry,$total); } } exit(0); sub printdir { my $dirtoprint=$_[0]; my $totalblocks=0; local *DIRHANDLE; my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = lstat $dirtoprint; if ($ERRNO != 0) { print "$dirtoprint: $!\n" if $opt_r; return 0; } if ($opt_l) { if (defined $filesystem) { if ($dev != $filesystem) { return 0; } } else { $filesystem=$dev; } } if (! opendir DIRHANDLE,$dirtoprint) { print "$dirtoprint: $!\n" if $opt_r; return 0; } my @allfiles=readdir DIRHANDLE; foreach $file (@allfiles) { next if $file =~ /^\.$/; next if $file =~ /^\.\.$/; if ($opt_x) { next if $file =~ /$opt_x/; } $file = "$dirtoprint/$file"; my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = lstat $file; if ($ERRNO != 0) { print "$file: $!\n" if $opt_r; next; } if ((-d $file) and (! -l $file)) { $totalblocks += printdir ($file); next; } if ($nlink > 1) { if ($inodes{"$dev$ino"}) { next; } else { $inodes{"$dev$ino"} = 1; } } $totalblocks += $blocks; if ($opt_a) { &printline($file,$blocks); } } closedir DIRHANDLE; my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = lstat $dirtoprint; $totalblocks += $blocks; if (! $opt_s) { &printline($dirtoprint,$totalblocks); } return $totalblocks; } sub printline() { my $filetoprint=$_[0]; my $sizetoprint=$_[1]; $sizetoprint /= 2 if $opt_k; print "$sizetoprint\t$filetoprint\n"; } sub printusage() { print "usage: du [-ahklrs] [-x ] [ ...]\n\n"; print "\t-a\tdisplay all files\n\n"; print "\t-h\tPrint this usage info\n\n"; print "\t-k\twill cause du to express all block counts in terms of \n\t\t1024 byte blocks. Default is 512 bytes.\n\n"; print "\t-l\tCompute diskusage for the same file system i.e don't\n\t\tdon't descend dir if file system changes.\n\n"; print "\t-r\tcomplain about dir/files which could not be opened.\n\t\tDefault is silent.\n\n"; print "\t-s\tcauses only the grand total of the names to be printed \n\n"; print "\t-x excludes files/dirs matching to be excluded from\n\t\tdisk usage accounting.\n\n"; }