When I run this program:
#!/usr/bin/perl -w
use File::Find;
use File::stat;
use Time::gmtime;
use Fcntl ':mode';
my %size = ();
my @directory = ('.');
find(
sub {
my $st = stat($File::Find::name) or die "stat failed for $File::Find::name : $!";
if ( defined $st )
{
my $gm = gmtime $st->mtime;
$size{$gm->year + 1900} += $st->blksize unless S_ISDIR($st->mode);
}
else
{
print "stat failed for ", $File::Find::name, ": $!\n";
}
},
@directory);
foreach my $year (keys %size)
{
print "$year ", $size{$year}, "\n";
}
I get stat failed for ./1128/00 : No such file or directory at ./size.pl line 13.
. But, when I list it, it's there:
# ls ./1128/00
03 05 07 09 12 14 18 20 22 24 27 29 32 34 37 40 43 45 47 50 52 54 57 59 63 65 67 69 75 78 81 83 85 88 90 92 95
04 06 08 11 13 15 19 21 23 25 28 31 33 35 39 41 44 46 48 51 53 55 58 61 64 66 68 71 77 79 82 84 86 89 91 93
Based on diagnostics that I have removed for this question, I can see that it does successfully stat the first 4 files and the .
directory and 1128
directory (parent to 1128/00
). It always successfully stats the same files and directories and fails on 1128/00
. Why is it failing?
By default, File::Find
will chdir
to each directory as it recurses.
Because of this, performing stat
on the $File::Find::name
value of ./1128/00
is actually looking for the file ./1128/./1128/00
, which does not exist.
To get the behavior that you want, simply perform your file operations on the $_
variable.
my $st = stat($_) or die "stat failed for $_: $!";