I'm using Perl 5.6.0 on Linux.
I've written a program to take a given directory passed in via command
line,
traverse the directory, and for each user who owns a file in that
directory,
print out their total usage.
My first attempt captured the directory using `ls -alR` and storing the
results in
an array. It worked, but I figured I might get more speed by using
File::Find and
File::stat. Now I have that program written, but there are some parts of
it that I'm
hoping to improve, and some parts I took from my O'Reilly Perl book, so
I don't
quite understand. I'm hoping you can help.
####################
In the following chunk of code, why is it necessary to put the \ before
the &Match ?
It's a reference, I guess, but I haven't wrapped my brain around it.
Is there a better way to pull out the uid and size of the file?
What about my if then else statement that checks to see if
$report{$owner} is defined?
Back months ago when I didn't use -w and strict, I used to be able to
say $report{$owner}+=$size,
but now I get complaints. Is there a better way to do this?
find (\&Match, "$ARGV[0]");
sub Match {
my $file=$File::Find::name;
if (-f $file) {
my $stats=stat($file);
my $owner=$stats->uid;
my $size=$stats->size;
(defined $report{$owner}) ? ($report{$owner}+=$size) :
($report{$owner}=$size);
}
}
#################
In the following chunk of code, $_ is a valid uid.
Is there a shorter, better way to get the username into the $name
variable?
my @info=getpwuid($_);
my $name;
(defined $info[0]) ? ($name=$info[0]) : ($name='unknown');
#################
My program follows (70 lines including lots of blank spaces), in case
someone wants to use it themselves or
even if some generous person has more comments to make. I understand
that this might not be the right place for a big "RFC on my program", so
feel
free to stop reading at this point .Thanks very much in advance.
Pete
#!/usr/bin/perl -w
use strict;
use File::Find;
use File::stat;
my %report;
my $threshhold=750*1024*1024 # Default is 750 MB
Args(); # Print help message and quit, change
threshhold
find (\&Match, "$ARGV[0]"); # Uses File::Find, matches using sub Match
Report();
#### SUBROUTINES ####
sub Args {
# Quit the program if no directory specified or threshhold is not an
integer.
if ((!defined $ARGV[0]) or (!-d $ARGV[0]) or ((defined $ARGV[1]) and
($ARGV[1]!~/^\d+$/))) {
print <<HELP;
Usage:
gethogs directory [threshhold in MB]
Default threshhold is $threshhold.
HELP
exit;
} else {
$threshhold=$ARGV[1] if (defined $ARGV[1]);
}
}
sub Match {
my $file=$File::Find::name;
if (-f $file) {
my $stats=stat($file);
my $owner=$stats->uid;
my $size=$stats->size;
(defined $report{$owner}) ? ($report{$owner}+=$size) :
($report{$owner}=$size);
}
}
sub Report { # Sort on values of hash,
not on keys.
foreach (sort { $report{$b} <=> $report{$a} } keys %report) {
if ($report{$_} >= $threshhold) {
my @info=getpwuid($_);
my $name;
(defined $info[0]) ? ($name=$info[0]) : ($name='unknown');
printf("%12s %12s\n",$name,Format($report{$_}));
}
}
}
sub Format { # Must be a better way, I think
my ($x)=@_;
if ($x<1024) {
return (sprintf("%6.2f B", $x));
}
$x=$x/1024;
if ($x<1024) {
return (sprintf("%6.2f kB", $x));
return "$x kB";
}
$x=$x/1024;
if ($x<1024) {
return (sprintf("%6.2f MB", $x));
return "$x MB";
}
$x=$x/1024;
return (sprintf("%6.2f GB", $x));
}
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]