File::Monitor multifunction PERL script

Follow up to previous question...

I got a great script from Clockwatcher and want to modify it so that it returns not just files added and deleted to the directory, but if existing files have changed since the initial scan.  I need the name of the file that changed as a return value,

Here is what I started with:

use File::Monitor;

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

$monitor->watch( {
        name        => 'c:/logs',
        callback    => \&SomethingHappened,
      files => 1
      }
    );
   

$monitor->scan();

for ($i=0; $i < 10; $i++)
{
      $monitor->scan();    
      sleep 10;
}

sub SomethingHappened
{
      my ($name, $event, $change) = @_;

      my @adds = $change->files_created;
      my @dels = $change->files_deleted;

      print "Added: ".join("\nAdded: ", @adds)."\n" if @adds;
      print "Removed: ".join("\nRemoved: ", @dels)."\n" if @dels;

}

I have tried variations of the line:
my @mods = $change(mtime);  but haven't had any luck.
LVL 1
itcs-cssAsked:
Who is Participating?
 
mjcoyneConnect With a Mentor Commented:
I don't have this module to check this out, but by reading the docs for File::Monitor::Delta (see http://search.cpan.org/~andya/File-Monitor-v0.0.5/lib/File/Monitor/Delta.pm), it looks as though if you add:

my @filestats = $change->is_metadata;

and:

print "Changed: ".join("\nChanged: ", @filestats)."\n" if @filestats;

you should be able to detect changes in the metadata of the file, which includes mtime, ctime, uid, gid and mode.
0
 
ozoConnect With a Mentor Commented:
print "Time changed: $name\n" if $change->is_time;
0
 
itcs-cssAuthor Commented:
Ozo...

The comment helps me start to understand how to call this function.  But adding this only works to add another print line for added or deleted files.

clockwatchers script is pretty specifically for watching one directory...what I need is a way to watch the files inside without knowing ahead of time which files are in there at the start of the monitor.
0
[Webinar] Improve your customer journey

A positive customer journey is important in attracting and retaining business. To improve this experience, you can use Google Maps APIs to increase checkout conversions, boost user engagement, and optimize order fulfillment. Learn how in this webinar presented by Dito.

 
ozoCommented:
If you are monitoring files addeed and removed, then you know at all times which files are  in there
0
 
itcs-cssAuthor Commented:
Sorry for not being clear on this.

I need to watch for 2 separate events...

a file is added or removed from the directory (clockwatcher's cover this perfectly)

a file that existed when the monitor was set has been updated with a config change (the mtime change is what I think will work for this)

What I see when I add the line above only seems to take effect on the added or deleted files.  I think my logic here is off in reading the File::Monitor docs.  It seems like an either/or directory or files function and not both.

Am I wrong in that aspect?
0
 
itcs-cssAuthor Commented:
mjcoyne...

I tried a few variations on that theme, but I only ever get "Changed" reports when a new file is added or an existing file is deleted and not any changes when existing files are modified.

I suspect it has to do with the explicit files => 1 in the given script, but taking it out doesn't seem to matter.  There seems to be a missing example in the docs on how something in here works.  :(
0
 
itcs-cssAuthor Commented:
It isn't pretty but this works by establishing multiple monitors that respond to the same looped scan...Now I just have to make it output the hash value in something human readable and I'll be on my way.

use File::Monitor;
use File::Monitor::Object;

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

chdir 'c:\\temp';
$temp = 'c:\\temp';

opendir DIR, $temp;
while ($file = readdir DIR) {
  next if $file =~ /^\./;
  push @files, $file;
}

#watch the files in the directory for changes
foreach (@files) {
$monitor->watch("$_", sub {
    my ($name, $event, $change) = @_;
    print "$name : $change \n";
    });
}

#Watch the directory for changes
$monitor->watch( {
        name        => "$temp",
        recurse     => 1,
        callback    => \&Test,
    } );

$monitor->scan;

for ($i=0; $i < 100; $i++)
{
      my @changes = $monitor->scan;  
      sleep 5;
}

sub Test
{
      my ($name, $event, $change) = @_;

      my @adds = $change->files_created;
      my @dels = $change->files_deleted;
     
      print "Added: ".join("\nAdded: ", @adds)."\n" if @adds;
      print "Removed: ".join("\nRemoved: ", @dels)."\n" if @dels;
}

0
All Courses

From novice to tech pro — start learning today.