【问题标题】:How do I archive .log files with Perl on Windows XP?如何在 Windows XP 上使用 Perl 归档 .log 文件?
【发布时间】:2016-03-31 21:08:00
【问题描述】:

以尽可能简单的方式,我想知道是否有人知道如何通过简单地将当前“localtime()”作为文件名的一部分命名它们来将 .log 文件归档到 Windows XP 目录中? (不要假设日志文件有锁。)我尝试了各种不同的方法,但无法解决它......而且网络上没有很好的例子。

这就是我要找的东西:

for (all files > that 1 day old)   
  rename file  to  file.[datestamp].log
end

【问题讨论】:

  • 你确定你有足够的理由重新发明/重新实现logrotate吗?
  • 为什么不使用'logrotate'?通常在大多数 linux 发行版上提供,或者如果使用不提供包的 nix 系统,则可以从源代码编译。
  • 是否有适用于 Windows XP 的 logrotate 二进制文件?
  • 您可能遇到的一个关键问题是,如果进程打开文件,文件可能会被“锁定”,从而阻止任何重命名操作成功。除非应用程序支持内部日志轮换,否则您将需要停止服务以轮换日志。此外,当您说“不起作用”时,请提供脚本中实际失败的详细信息。
  • 我尝试向这个问题添加代码示例,但它所做的只是分散人们回答问题的注意力,所以我编辑了我的示例代码。

标签: windows perl logging archiving


【解决方案1】:

嗯,这看起来很简单,我可能误解了一些东西。任务是将例如“yada.log”移动到“yada.2011-05-04.log”?那么这个怎么样:

use strict;
use warnings;

use File::Copy;
use POSIX qw(strftime);

my $dir = $ARGV[0] or die "Usage: $0 <directory>";
my $now_string = strftime "%Y-%m-%d_%H%M%S", localtime;

opendir DIR, $dir or die $!;
my @files = readdir DIR;

chdir $dir or die $!;
for my $file (@files) {
    next if (-d $file);
    next unless ($file =~ /^(.*)(\.log)$/i);
    my $dst = $1 . "." . $now_string . $2;
    move ($file, $dst) or die "Failed to move $file: $!";
}

【讨论】:

  • 您的脚本适用于我,但它不需要存档已存档的文件。我没有在我的问题中这么说,但这就是我的意思。
  • 是的,我刚才想到了..next if ($file =~ /20\d{2}-\d{2}-\d{2}_\d{6}\.log$/i); 应该这样做(未来 89 年)。无论如何,有了这个日期戳......我没有把它做得很漂亮,恐怕,只有功能。
【解决方案2】:
opendir(FILES, '*logdir*');
my @files = readdir FILES;
closedir(FILES);
foreach(@files){
    system "move $_ $_.".localtime().".log" if -A $_ > *age*;
}

【讨论】:

    【解决方案3】:

    感谢 TLP,我最终是这样做的!这个脚本在第 12 行有问题,但几乎没有用。

    use strict; 
    use warnings;
    use File::Copy; 
    use POSIX qw(strftime); 
    
    my $dir;
    my $file;
    
    if ( @ARGV = 2 ) { 
      print "Two args accepted."; 
      $dir = $ARGV[0] or die "Usage: <directory> <filename>";
      $file = $ARGV[1] or die "Usage: <directory> <filename>";
      goto runblock; 
    }
    else { print "Number of arguments must be 2: directory filename\n"; goto fail; }
    
    runblock: print "Renaming $file .\n";
    
    chdir $dir or die $!;
    my $now_string = strftime "%Y-%m-%d_%H%M%S", localtime; 
    if (-e $file) {
      if (-A $file > 7 ) {
        my $dst = "siteAlive." . $now_string . ".log"; 
        move($file, $dst) or die "Failed to move $file: $!";
        goto endscript;
      }
    } 
    
    fail: print "Failed to rename $file . Try again.\n" ;
    endscript: print "End of script.\n";
    

    【讨论】:

    • if ( @ARGV = 2 ) 会导致一个细微的错误。你想要的是if ( @ARGV == 2 ),检查值,否则你给它分配一个新值。
    • 你改变了一些事情:你没有保留原始文件的部分名称(它们都被称为 siteAlive),你检查超过 7 天的访问时间而不是 1,并且您仅在单个文件上运行它。我不确定这是否是故意的。如果您需要更多帮助,请告诉我。
    • 谢谢。是的,我想要“一般”的答案,但我也想使用我在特定场景中学到的知识。
    【解决方案4】:

    也许有一些模块可以为你做到这一点,例如 Logfile::Rotate

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-08
      • 1970-01-01
      • 2014-06-17
      相关资源
      最近更新 更多