perl之在 perl 中使用 inotify 观看多个文件

shanyou 阅读:50 2024-06-20 12:54:19 评论:0

我需要在 Perl 中观看多个文件,我正在使用 Linux::Inotify2 .但是我遇到了一个问题,需要修改和点击正在观看的第一个文件,然后是第二个,然后是第一个等等

例如,如果第二个文件在第一个文件之前更改,则不会触发,或者如果第一个文件连续触发两次而没有触发第二个文件。

这是我正在使用的存在此问题的代码部分。

my $inotify = new Linux::Inotify2; 
my $inotify2 = new Linux::Inotify2; 
$inotify->watch ("/tmp/rules.txt", IN_MODIFY); 
$inotify2->watch ("/tmp/csvrules.out", IN_MODIFY); 
 
while () { 
  my @events = $inotify->read; 
  unless (@events > 0){ 
    print "read error: $!"; 
    last ; 
  } 
 
  foreach $mask (@events) { 
    printf "mask\t%d\n", $mask; 
 
    open (WWWRULES, "/tmp/rules.txt"); 
 
    my @lines = <WWWRULES>; 
    foreach $line (@lines) { 
      @things = split(/,/, $line); 
      addrule(@things[0], @things[1], @things[2], @things[3], trim(@things[4])); 
      print "PRINTING: @things[0], @things[1], @things[2], @things[3], @things[4]"; 
      close (WWWRULES); 
      open (WWWRULES, ">/tmp/rules.txt"); 
      close (WWWRULES); 
    } 
  } 
 
  my @events2 = $inotify2->read; 
  unless (@events2 > 0){ 
    print "read error: $!"; 
    last ; 
  } 
  foreach $mask (@events) { 
    printf "mask\t%d\n", $mask; 
    open (SNORTRULES, "/tmp/csvrules.out"); 
 
    my @lines2 = <SNORTRULES>; 
    foreach $line2 (@lines2) { 
      @things2 = split(/,/, $line2); 
      addrule("INPUT", @things2[0], @things2[1], @things2[2], trim(@things2[3])); 
      print "PRINTING: INPUT, @things2[0], @things2[1], @things2[2], @things2[3]"; 
 
      close (SNORTRULES); 
      open (SNORTRULES, ">/tmp/csvrules.out"); 
      close (SNORTRULES); 
    } 
  } 
} 

理想情况下,我想观看 3 个文件,但由于我无法让 2 个文件工作,因此在现阶段似乎有点毫无意义。

谢谢你的帮助!

请您参考如下方法:

单个 inotify 对象可以处理任意数量的 watch 。这是 inotify 相对于较旧且现已过时的 dnotify 的优势之一。所以你应该说:

my $inotify = Linux::Inotify2->new; 
$inotify->watch("/tmp/rules.txt", IN_MODIFY); 
$inotify->watch("/tmp/csvrules.out", IN_MODIFY); 

然后你可以通过查看 fullname 来查看触发了哪个 watch 。事件对象的属性:
while () { 
  my @events = $inotify->read; 
  unless (@events > 0){ 
    print "read error: $!"; 
    last ; 
  } 
 
  foreach my $event (@events) { 
    print $event->fullname . " was modified\n" if $event->IN_MODIFY; 
  } 
} 

最大的问题是您的代码正在修改您正在查看修改的相同文件。当 /tmp/rules.txt被修改,你打开它,阅读它,然后截断它,这会触发另一个修改通知,重新开始整个过程​​。一般来说,如果没有竞争条件,这很难解决,但在您的情况下,您应该能够只检查空文件( next if -z $event->fullname )。


标签:程序员
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号