3

Perlで複数のファイルを監視する必要があり、Linux::Inotify2を使用しています。ただし、監視対象の最初のファイルを変更してヒットし、次に2番目、次に最初のファイルなどをヒットする必要があるという問題が発生しています。

たとえば、2番目のファイルが最初のファイルの前に変更された場合、それはトリガーされません。または、最初のファイルが2回続けてトリガーされ、2番目のファイルが間にトリガーされない場合です。

これは私が使用しているコードのセクションで、この問題が発生しています。

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つは動作しないので、この段階では少し無意味に思えます。

助けてくれてありがとう!

4

2 に答える 2

11

1つのinotifyオブジェクトで、任意の数の時計を処理できます。これは、古い、現在は廃止されたdnotifyに対するinotifyの利点の1つです。だからあなたは言うべきです:

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

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;
  }
}

大きな問題は、コードが変更を監視しているのと同じファイルを変更していることです。が変更されたら/tmp/rules.txt、それを開いて読み取り、切り捨てます。これにより、別の変更通知がトリガーされ、プロセス全体が最初からやり直されます。一般に、これは競合状態なしでは解決するのが難しいですが、あなたの場合、空のファイル()をチェックするだけでよいはずですnext if -z $event->fullname

于 2011-03-15T19:24:03.380 に答える
0

並行して実行したいことを連続してチェックしているようです。別のプロセスをフォークするか、スレッド化を使用するか、POEオブジェクトと統合する必要があります。

アプリケーションで機能する場合と機能しない場合がある別のオプションは、tempdirをより具体的なものに設定し、作業中のすべてのファイルをそこに保持してから、ディレクトリ全体を監視することです。これにより、1つだけが必要になります。私がこの権利を読んでいるなら、オブジェクトをinotifyします。(私は特にこのモジュールで何もしていませんが、システムコールをファイルシステムにフックすることによってそれがどのように機能するかについてかなり良い考えを持っています)。

于 2011-03-15T18:35:02.760 に答える