【问题标题】:check last modified file in directory检查目录中最后修改的文件
【发布时间】:2016-08-01 06:58:27
【问题描述】:

我的脚本检查这个目录/var/spool/gammu/inbox/中最后修改的文件

#!/usr/bin/perl -w
use strict;
use warnings;
chomp (my $dirname ='/var/spool/gammu/inbox/');
my $newest_file = do {
opendir my $dh, $dirname or die "Could not open '$dirname' for reading: $!\n";
my @by_age  = sort { -M $a <=> -M $b } grep -f, readdir ($dh);
$by_age[0];
};

open my $file, '<', $newest_file or die qq{Unable to open "$newest_file" for input: $!};
my @rows = <$file>;
close ($file);
print "@rows\n";

我明白了:

在 ./checken.pl 第 16 行打开时使用未初始化的值 $newest_file。

在 ./checken.pl 第 16 行的连接 (.) 或字符串中使用未初始化的值 $newest_file。

无法打开“”进行输入:./checken.pl 第 16 行的 Datei oder Verzeichnis nicht gefunden。

【问题讨论】:

    标签: perl file directory dirname


    【解决方案1】:

    也许我在my solution to your previous question 中没有足够强调这一点。我写了

    如果您想对 cwd 以外的目录执行此操作,那么只需 chdir 并使用此代码可能最简单,而不是尝试 opendir 特定目录,因为您将不得不构建每个文件的完整路径才能使用-M

    问题是readdir返回的数据只是一个没有任何路径信息的裸文件名,如果文件在当前工作目录以外的目录下不添加路径信息就找不到

    如果你只是先chdir 到目录,那么一切都会正常工作。这是您的代码的整理版本

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    chomp(my $dirname = "/var/spool/gammu/inbox/");
    chdir $dirname or die qq{Unable to chdir to "$dirname": $!};
    
    my $newest_file = do {
        opendir my $dh, '.' or die "Could not open '$dirname' for reading: $!\n";
        my @by_age  = sort { -M $a <=> -M $b } grep -f, readdir ($dh);
        $by_age[0];
    };
    
    open my $file, '<', $newest_file or die qq{Unable to open "$newest_file" for input: $!};
    print while <$file>;
    

    或者,如果您有理由避免更改程序中的目录(一旦程序退出,更改将不会反映在您的 shell 中),那么您应该使用File::Spec::Functions 中的rel2abs 来构建完整的使用它之前的文件路径

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    use File::Spec::Functions 'rel2abs';
    
    chomp(my $dirname = "/var/spool/gammu/inbox/");
    
    my $newest_file = do {
        opendir my $dh, '.' or die "Could not open '$dirname' for reading: $!\n";
        my @files = map { rel2abs($_, $dirname) } grep -f, readdir ($dh);
        my @by_age  = sort { -M $a <=> -M $b } @files;
        $by_age[0];
    };
    
    open my $file, '<', $newest_file or die qq{Unable to open "$newest_file" for input: $!};
    print while <$file>;
    

    其他几点

    • use warnings 在命令行上优于-w。你不应该同时使用这两个

    • 除非需要,否则最好避免将整个文件读入内存。一次可以读取和打印一个文件

    【讨论】:

    • 谢谢 :))))))))))))
    【解决方案2】:

    我建议您使用map 在文件之前添加目录名称(以提供绝对路径),然后将其提供给grep

    它应该如下所示:

    my @by_age  = sort {-M $a <=> -M $b} grep {-f $_} map {"$dirname/$_"} readdir ($dh);
    

    【讨论】:

    • 我怎样才能让这个脚本在 while 或 for 下运行。每次脚本检查我是否有新文件。
    • 将其包裹在while(1) { sleep(your seconds)}下。
    • 脚本每次都检查目录,并且应该只在创建新文件时提供答案。
    • 那么,或许你应该看看File::ModifiedFile::Monitor
    • @perlfg:您尚未接受任何问题的答案。请检查:meta.stackexchange.com/questions/5234/…
    猜你喜欢
    • 2016-04-03
    • 1970-01-01
    • 2012-02-15
    • 2012-05-29
    • 2015-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-22
    相关资源
    最近更新 更多