【发布时间】:2017-10-18 22:46:37
【问题描述】:
我正在尝试清理一个相当大的文件系统。我使用stat函数来获取每个文件的修改时间。
根据perldoc -f stat,返回列表的第十个元素是自纪元以来的最后修改时间,以秒为单位。
我用DateTime->from_epoch 减去DateTime->now 来计算燃料的年龄
#!/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;
}
如果我手动创建测试文件并更改修改时间,结果是关闭了 30 天
$ 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'
};
我尝试了DateTime 对象,无论是否设置时区,结果都没有差异。
$ 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
工作解决方案:
#!/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;
【问题讨论】:
-
你考虑过
-M $file吗?这是脚本开始时间(所以,“现在”)和最后修改时间之间的差异,这似乎是您需要的。见file tests (-X)。 -
请查看您发布的内容。
$self->{dir} ...不应该在strict下编译(而且没有任何意义) -
你会发现要获得完整的持续时间,仅仅调用 in_units('days') 是不够的。查看 DateTime::Duration 文档,您可能会错过几个月甚至几年而没有意识到这一点。在这里直接使用纪元数和秒数可能会更容易。
-
您发布的代码缺少大量内容,这将使其成为一个完整的、独立的示例。就目前而言,这是胡言乱语。但是,大约 30 天的 delta 似乎向我表明,您错过了基于 Perl 或类似内容的月份为零的事实。这是我要寻找的第一件事。
-
如果您相隔一年创建两个 DateTime 对象,将它们相减以获得持续时间,然后调用 in_unit('days'),您会得到 ... 0。这是由于 DateTime 数学和文档中提到。