Perl "malfunction"

Go to solution
Adam W.
Valued Contributor

Perl "malfunction"

I am not a perl master by any means, but I have attached a script that gives the amount of space used by each user in /home. My problem is that it is not reporting all users, it is only reporting some users. What is wrong with this? Can anyone tell me what I am missing?
There are two types of people in the world, Marines and those who wish they were.
James R. Ferguson
Acclaimed Contributor

Re: Perl "malfunction"

Hi Adam:

You will avoid chasing silly mistakes if you always use the 'strict' and 'warnings' pragma!

use strict;
use warnings;

If this is not reporting all users, perhaps it is because you have '/home' directories smaller than 1% of the total.

I regret to say that this Perl script isn't very Perl-ish. You might want to look into the 'File::Find' module and the 'stat()' function. The module will search as directory and 'stat()' can tell the size of files and/or directories within. You could also use 'readdir()' to read entries in your directories. Essentially your Perl script uses a hash to tally and report overall directory sizes, but it makes lots of external calls to do so.


H.Merijn Brand (procura
Honored Contributor

Re: Perl "malfunction"

Why use perl for a thing like this?

# cd /home
# du -sk *

BTW as an addition to what JRF said, a perl way to check the size of a file without a system call or perl function, is using '-s $file', which will return the size of $file

--8<--- untested braindump:
use strict;
use warnings;
use File::Find;

chdir "/home";
my $space;
foreach my $user (glob "*) {
find (sub { $space{$user} += -s $_ },$user);
printf "%9d %s\n", $space{$_}, $_ for sort { $space{$a} <=> $space{$b} } keys %space;

Enjoy, Have FUN! H.Merijn
Enjoy, Have FUN! H.Merijn
Hein van den Heuvel
Honored Contributor

Re: Perl "malfunction"

The above comments stand. strict, warnings ans such.

But I can see some merrit in the script.
It starts to build an array, but does not (yet) use it.
It could learn gather data first just once and then print when all data is there.

Here is a slight improvement suggestion.
It sorts by descending usage.
Note how it handles Totat in the loop.

Also Untested (on hpux. HP test-drive is now gone and I still have to set up an alternative or re-boot my rx to run hpux instead of VMS. I did give it a quick run on my linux music-player :-).


my $home_thresh = 1 ;
my $top = 10;

foreach (`du -sk /home/* 2> \/dev\/null` ) {
chop ;
($home_kb,$home_dir) = split (/\s+/);
$home_total += $home_kb;
$homes_size{$home_dir} = $home_kb ;

$homes_size{"Total"} = $home_total;

print "Top $top users larger than $home_thresh%\n";

foreach (sort { $homes_size{$b} <=> $homes_size{$a} } keys %homes_size ) {
$home_pct = int(($homes_size{$_} / $home_total) * 100) ;
last unless $top--;
last if $home_pct < $home_thresh;
print "$_ ($homes_size{$_} kb) is $home_pct% \n" ;

Adam W.
Valued Contributor

Re: Perl "malfunction"

Thanks guys! I will heed your words, and correct this. Thanks again!
There are two types of people in the world, Marines and those who wish they were.