Dra*_*ake 3 perl file-io inotify
我需要在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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
理想情况下,我想看3个文件,但由于我无法工作,所以在这个阶段似乎有点无意义.
谢谢你的帮助!
cjm*_*cjm 10
单个inotify对象可以处理任意数量的手表.这是inotify相对于旧版本和现在过时的dnotify的优势之一.所以你应该说:
my $inotify = Linux::Inotify2->new;
$inotify->watch("/tmp/rules.txt", IN_MODIFY);
$inotify->watch("/tmp/csvrules.out", IN_MODIFY);
Run Code Online (Sandbox Code Playgroud)
然后,您可以通过检查fullname事件对象的属性来查看触发了哪个监视:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
最大的问题是您的代码正在修改您正在观看修改的相同文件.当/tmp/rules.txt被修改,你打开它,阅读它,然后截断它,这会触发另一个修改的通知,开始整个过程从头再来.一般来说,如果没有竞争条件,这很难解决,但在你的情况下,你应该只能检查一个空文件(next if -z $event->fullname).