I am trying to clean up a rather large file system. I use the stat
function to obtain the modification time of each file.
According to perldoc -f stat
, the tenth element of the returned list is the last modified time in seconds since the epoch.
I use DateTime->from_epoch
and subtract DateTime->now
to calculate the age of the fule
#!/usr/bin/perl
use strict;
use warnings;
use DateTime;
my $now = DateTime->now();
#my $now = DateTime->now( time_zone => "America/New_York" );
$self->{dir} = '/tmp/test';
opendir(DIR, $self->{dir}) or die $@;
my @files = grep(/\.txt$/, readdir(DIR));
closedir(DIR);
for ( @files ) {
my $file = stat($self->{dir} . '/' . $_);
my $mtime = DateTime->from_epoch(epoch => $file->mtime);
#my $mtime = DateTime->from_epoch(epoch => $file->mtime, time_zone=> "America/New_York");
my $elapsed = $now - $mtime;
push(@{$self->{stale}}, {file => $self->{dir} . '/' . $_, mtime => $elapsed->in_units('minutes')}) if $elapsed->in_units('minutes') > 15;
push(@{$self->{remove}}, {file => $self->{dir} . '/' . $_, mtime => $elapsed->in_units('days')}) if $elapsed->in_units('days') > 10;
}
If I manually create test files and change the modification time, the result is off by 30 days
$ touch /tmp/test/test{100..104}.txt -d '-45 days'
$ perl MTIME.pm
$VAR1 = {
'mtime' => 15,
'file' => '/tmp/test/test100.txt'
}; $VAR1 = {
'mtime' => 15,
'file' => '/tmp/test/test104.txt'
}; $VAR1 = {
'mtime' => 15,
'file' => '/tmp/test/test103.txt'
}; $VAR1 = {
'mtime' => 15,
'file' => '/tmp/test/test101.txt'
}; $VAR1 = {
'mtime' => 15,
'file' => '/tmp/test/test102.txt'
};
I've tried DateTime
objects both with and without the time zone set with no difference in results.
$ touch /tmp/test/test{100..104}.txt -d '-45 days'
$ touch /tmp/test/test{105..110}.txt
$ ll /tmp/test
total 11
-rw-r--r-- 1 root root 0 Apr 3 19:31 test100.txt
-rw-r--r-- 1 root root 0 Apr 3 19:31 test101.txt
-rw-r--r-- 1 root root 0 Apr 3 19:31 test102.txt
-rw-r--r-- 1 root root 0 Apr 3 19:31 test103.txt
-rw-r--r-- 1 root root 0 Apr 3 19:31 test104.txt
-rw-r--r-- 1 root root 0 May 18 19:30 test105.txt
-rw-r--r-- 1 root root 0 May 18 19:30 test106.txt
-rw-r--r-- 1 root root 0 May 18 19:30 test107.txt
-rw-r--r-- 1 root root 0 May 18 19:30 test108.txt
-rw-r--r-- 1 root root 0 May 18 19:30 test109.txt
-rw-r--r-- 1 root root 0 May 18 19:30 test110.txt
Working solution:
#!/usr/bin/perl
use strict;
use warnings 'all';
use Data::Dumper;
my $self = bless { }, 'My::Class';
my @files = glob '/tmp/test/*.txt';
for (@files) {
my $days = int(-M $_);
my $mins = int((time - (stat $_)[9]) / 60);
my $item = {
file => $_,
days => $days,
minutes => $mins
};
push @{ $self->{remove} }, $item if $days > 10;
push @{ $self->{stale} }, $item if $mins > 15;
}
print Dumper $self;