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?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

ozoCommented:
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
ozoCommented:
If you are monitoring files addeed and removed, then you know at all times which files are  in there
0
Cloud Class® Course: Microsoft Exchange Server

The MCTS: Microsoft Exchange Server 2010 certification validates your skills in supporting the maintenance and administration of the Exchange servers in an enterprise environment. Learn everything you need to know with this course.

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
mjcoyneCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Perl

From novice to tech pro — start learning today.