Perl File::Monitor 模块为创建的新文件通知多个通知,而我期望一个通知

Posted

技术标签:

【中文标题】Perl File::Monitor 模块为创建的新文件通知多个通知,而我期望一个通知【英文标题】:Perl File::Monitor module notifying multiple notifications for the new file created whereas i expect one notification 【发布时间】:2016-02-08 07:54:27 【问题描述】:

下面是代码sn-p!我正在使用 Perl 模块 File::Monitor 进行文件创建通知。

#!/usr/bin/perl

use strict;
use warnings;
use File::Monitor;
use File::Basename;
use Time::HiRes qw usleep;

my $pid,@pids;


sub textfile_notifier 
my ($watch_name, $event, $change) = @_; 

my @new_file_paths = $change->files_created; #The change object has a property called files_created, 
                                             #which contains the names of any new files
for my $path (@new_file_paths) 
    my ($base, $fname, $ext) = fileparse($path, '.log'); # $ext is "" if the '.txt' extension is
                                                         # not found, otherwise it's '.txt'.
    if ($ext eq '.log') 
        print "$path was created\n";
    #-----------------------------------------Forking part #-----------------------------------------
    defined ($pid = fork()) or die "Couldn't fork: $!";
    if ($pid == 0)  #then in child process
        print "Loop got executed\n";
    
    else   #then in parent process, where $pid is the pid of the child
        push @pids, $pid;
    
    #-----------------------------------------Forking part ends here #-----------------------------------------
    



my $monitor = File::Monitor->new();

$monitor->watch( 
name        => '/home/goudarsh/Desktop/logs/',
recurse     => 1,
callback    => files_created => \&textfile_notifier,  #event => handler 1 
 );

$monitor->scan;
while (1) 
$monitor->scan; #Scanning the directory one
#sleep(2);
#usleep(10_000); #$microseconds = 750_000;
for my $pid (@pids) 
    waitpid($pid, 0)  #0 => block


文件创建

==============================

touch 1.log  
touch 2.log  
touch 3.log  
touch 4.log  

脚本的输出

===========================

/home/goudarsh/Desktop/logs/1.log was created  
/home/goudarsh/Desktop/logs/2.log was created  
/home/goudarsh/Desktop/logs/2.log was created  
/home/goudarsh/Desktop/logs/3.log was created  
/home/goudarsh/Desktop/logs/3.log was created  
/home/goudarsh/Desktop/logs/3.log was created  
/home/goudarsh/Desktop/logs/4.log was created  
/home/goudarsh/Desktop/logs/3.log was created  
/home/goudarsh/Desktop/logs/4.log was created  
/home/goudarsh/Desktop/logs/4.log was created  
/home/goudarsh/Desktop/logs/4.log was created  
/home/goudarsh/Desktop/logs/4.log was created  
/home/goudarsh/Desktop/logs/4.log was created  
/home/goudarsh/Desktop/logs/4.log was created  
/home/goudarsh/Desktop/logs/4.log was created      

我期望在终端上为一个文件打印一个通知/警报。 我怀疑“分叉部分”部分存在一些错误!

知道我哪里做错了吗?

【问题讨论】:

您是否尝试过在打开 for 循环之前从数组中删除重复项? 编辑: 文件一个接一个创建的速度有多快? @Phyreprooph 你在说哪些重复的条目?并且文件是随机生成的 @7stud 你能帮帮我吗 抱歉,我说的是@new_file_paths 中可能存在的重复项。这可能是打印出多种内容的原因。或者,备份您的脚本并删除分叉部分并查看打印出来的内容。这会告诉你是否是导致此问题的分叉部分 @Phyreprooph 是的,你是对的!移除 fork 部分后它工作正常,我最初的想法是使用 fork 在if ($pid == 0) #then in child process system("perl $script $path \&"); 中执行脚本,我不知道我可以直接做到这一点!这就是我使用 fork 的原因,看起来它对我来说很好用 【参考方案1】:

这就是解决我的问题的方法

use strict;
use warnings;
use File::Monitor;
use File::Basename;
use Time::HiRes qw usleep;
my $script = '/homw/goudarsh/Desktop/script.pl';
sub textfile_notifier 
my ($watch_name, $event, $change) = @_; 

my @new_file_paths = $change->files_created; #The change object has a property called files_created, 
                                         #which contains the names of any new files
for my $path (@new_file_paths) 
my ($base, $fname, $ext) = fileparse($path, '.log'); # $ext is "" if the '.txt' extension is
                                                     # not found, otherwise it's '.txt'.
if ($ext eq '.log') 
    print "$path was created\n";
    system("perl $script $path \&");


my $monitor = File::Monitor->new();
$monitor->watch( 
name        => '/home/goudarsh/Desktop/logs/',
recurse     => 1,
callback    => files_created => \&textfile_notifier,  #event => handler 1 
 );

$monitor->scan;
while (1) 
$monitor->scan; #Scanning the directory one
sleep(2);
#usleep(10_000); #$microseconds = 750_000;


我只想以$path 作为参数来执行$script,并且我使用fork 来创建子进程,但是我对使用fork 的概念是错误的,这是不需要的!现在无需分叉,我可以做任何需要的事情,我很高兴学习新事物

【讨论】:

但我仍然不明白为什么我在使用 fork 时会收到多个条目。 您没有在子节点中退出,因此父节点和子节点都在继续循环、监视和再次分叉。第一次,一个过程。第二次,两个过程。第三次,四个过程。第四次,八个进程。 如果您修改的文件更多(例如,十多个),您最终会得到数千个进程的监控和打印。 我实际上仍然有旧的行为,即。 ,首先报告1个日志,然后是2、4、8等。我使用代码作为上面的答案,只是我添加了my (@pids);来处理编译警告。 @gsl 请删除不再需要的 for 循环

以上是关于Perl File::Monitor 模块为创建的新文件通知多个通知,而我期望一个通知的主要内容,如果未能解决你的问题,请参考以下文章

Perl 更常称为变量声明

perl命令

perl线程和模块

Perl-Tk入门教程 - 创建一个窗口

如何将 Perl 模块发布到 CPAN?

如何使用多个版本的 Perl 在 Perl 模块中安装脚本?