Here is a PERL script to do the job.
The author is Kjetil Torgrim Homme <kjetilho_at_ifi.uio.no>.
Thanks to everybody who replied.
Paul
The script:
#!/local/bin/perl
use Getopt::Std;
&init;
&dodir($dir);
&report;
&cleanup;
sub dodir {
my (_at_dirs, $file, _at_stats);
chdir ($_[0]) || return warn "can't chdir $_[0]: $!\n";
opendir (DIR, ".") || return warn "can't open $_[0]: $!\n";
_at_dirs = ();
while ($file = readdir DIR) {
next if $file eq "." || $file eq "..";
_at_stats = lstat $file;
next if $#stats == -1; # usually file removed under our feet
# dev 0, ino 1, mode 2, nlink 3, uid 4, gid 5, rdev 6, size 7,
# atime 8, mtime 9, ctime 10, blksize 11, blocks 12
$uid = $stats[4];
next if $uid == 65534 || $uid == 60001;
$kb = $stats[12] / 2;
##
## To avoid miscalculating multiply linked files, we divide by
## the number of links. We don't do this for directories, since
## the other hardlinks are "." and ".." which we always skip.
##
$kb /= $stats[3] if ! -d _;
$du_byuid[$uid] += $kb;
if ($opt_v) {
$du1m_byuid[$uid] += $kb if ($stats[8] < $ago1months);
$du2m_byuid[$uid] += $kb if ($stats[8] < $ago2months);
$du3m_byuid[$uid] += $kb if ($stats[8] < $ago3months);
}
next if $opt_x && $stats[0] != $device;
##
## Remember to check this later, unless it's a .snapshot directory
## on a NetApp.
##
push (_at_dirs, $file) if (-d _ && ($uid || $file ne ".snapshot"));
}
closedir (DIR);
for (_at_dirs) {
&dodir ($_);
}
chdir ("..") || die "can't chdir .. from $_[0]: $!\n";
}
sub report {
my ($i, %used, _at_report, $uid);
##
## Build an array of users with non-zero usage
##
for ($i = 0; $i <= $#du_byuid; $i++) {
next unless defined $du_byuid[$i] && $du_byuid[$i] > 0;
$used{$user_byuid[$i]} = $du_byuid[$i];
}
##
## Sort it into descending order
##
_at_report = sort { $used{$b} <=> $used{$a} } keys %used;
for (_at_report) {
if ($opt_v) {
$uid = $uid_byuser{$_};
printf("%7d\t%-8s\t%7d %7d %7d\n", $used{$_}, $_,
$du1m_byuid[$uid], $du2m_byuid[$uid], $du3m_byuid[$uid]);
} else {
printf("%7d %s\n", $used{$_}, $_);
}
}
}
sub usage {
my ($me);
$me = $0; $me =~ s,.*/,,;
print STDERR
"Usage: $me [options] [directory]
Options are:
-v display three columns containing the number of blocks not
accessed in the last 30, 60, and 90 days.
-n NETAPP connect to NETAPP and create a snapshot before starting.
-x stay in one filesystem.\n";
exit (64);
}
##
## init sets the following globals:
## $dir Directory to investigate
## _at_du_byuid Total disk usage
## _at_user_byuid Lookup username by numeric uid
## %uid_byuser Lookup numeric uid by username
##
## $opt_n Name of NetApp
## $snap Name of snapshot
## $opt_v Boolean
## $ago{1,2,3}months Times for comparing file age
## _at_du{1,2,3}m_byuid Accumulators for several file ages
## $opt_x Boolean
## $device Device number to investigate
##
sub init {
&usage unless getopts ('vxn:');
$SIG{'INT'} = $SIG{'TERM'} = $SIG{'HUP'} = 'cleanup';
$dir = $#ARGV == 0 ? $ARGV[0] : ".";
print "$dir:\n";
if ($opt_v) {
$ago1months = time - (1 * 30 * 86400);
$ago2months = time - (2 * 30 * 86400);
$ago3months = time - (3 * 30 * 86400);
}
##
## Create a snapshot.
##
if ($opt_n) {
$snap = "quot.$dir.$$"; $snap =~ s/[^\w\d]+/./g;
system ("rsh -n $opt_n snap create $snap >&2 &");
$dir .= "/.snapshot/$snap";
}
##
## Prime the arrays to avoid undefined values.
##
setpwent;
while (_at_u = getpwent) {
next if $u[2] == 65534 || $u[2] == 60001;
$user_byuid[$u[2]] = $u[0];
$uid_byuser{$u[0]} = $u[2];
}
endpwent;
##
## Fill in unknown values
##
local ($i);
for ($i = 0; $i <= $#user_byuid; $i++) {
$du_byuid[$i] = 0;
$du1m_byuid[$i] = $du2m_byuid[$i] = $du3m_byuid[$i] = 0 if $opt_v;
next if defined $user_byuid[$i];
$user_byuid[$i] = "#$i";
$uid_byuser{"#$i"} = $i;
}
##
## Wait until the snapshot has been developed.
##
if ($opt_n) {
while (! -d $dir) {
sleep (1);
}
}
if ($opt_x) {
$device = (lstat ($dir))[0];
}
}
sub cleanup {
if ($opt_n && defined $snap) {
# system ("rsh $opt_n snap delete $snap >&2");
system ("rsh $opt_n snap delete $snap > /dev/null");
}
exit (0);
}
_____________________________________________________________________
|R| A Message from Paul Key: Reginet Systems Developer
|E| at
|G| The Institute of Public & Environmental Health,
|I| The University of Birmingham,
|N|
http://www.hsrc.org.uk
|E| E-mail : Paul_at_hsrc.org.uk
|T| Telephone : 0 (+44) 121 456 5600 Ext. 59875
| | Fax / Messages : 0 (+44) 121 454 6876
______________________________________________________________________
Received on Wed Apr 09 1997 - 12:16:36 NZST