Perl:读取目录,直到文件存在

Aru*_*ngh 1 perl

我正在编写一个简单的程序来检查目录中是否存在文件.该文件由一些外部程序创建,没有统一的时间.所以,我需要在循环中检查文件是否存在,因为我需要在它出现时立即处理它.

即使文件已创建,此程序也会连续运行.

#!/usr/bin/perl
use strict;
use warnings;


my $dir = "/my/path";
opendir( my $dh, $dir ) || die "can't opendir $dir: $!";
my @files = grep { /^[^\.]/ && -f "$dir/$_" } readdir($dh);
until (@files) {
    print "No files Found: Sleeping for a sec\n";
    sleep(1);
    @files = grep { /^[^\.]/ && -f "$dir/$_" } readdir($dh);
}
print @files;
Run Code Online (Sandbox Code Playgroud)

以下程序按预期工作.

#!/usr/bin/perl
use strict;
use warnings;


my $dir = "/my/path";
opendir( my $dh, $dir ) || die "can't opendir $dir: $!";
my @files = grep { /^[^\.]/ && -f "$dir/$_" } readdir($dh);
closedir $dh;
until (@files) {
    opendir( my $dh, $dir ) || die "can't opendir $dir: $!";
    print "No files Found: Sleeping for a sec\n";
    sleep(1);
    @files = grep { /^[^\.]/ && -f "$dir/$_" } readdir($dh);
    closedir $dh;
}

print @files;
Run Code Online (Sandbox Code Playgroud)

我想知道这两种方法的区别.为什么前一个没有工作,即使我每次在循环中读取目录.为什么我需要每次在循环中打开目录才能使其工作?

zdi*_*dim 6

这是因为在readdir之后,目录句柄到达了文件列表的末尾,所以即使同时添加了文件,下次也没有什么可读的.当在列表上下文中使用句柄时,会在第一次读取时发生这种情况.

您可以向循环添加对rewinddir的调用,这会将目录句柄移回到下一个目录的开头readdir.

或者,使用glob并将测试放在until条件中

my $cond = qr(^[^\.]); 

until (grep { $cond && -f } glob "$dir/*") { 
    say "no files"; 
    sleep 1;
}
Run Code Online (Sandbox Code Playgroud)

这样,每次测试都会重新读取目录.由于glob返回路径,这简化了事情.

它也可以缩短为

my @files;

sleep 1 until @files = grep { $cond && -f } glob "$dir/*";

say for @files;
Run Code Online (Sandbox Code Playgroud)