Monitoring File Changes

C

Clifford Bracht

I'm a newbie with Perl Scripts and I need to write a small script. I
have a File that is constently being monitored, and I would like to
create a script that would notify me whenever there is any change at
all made to that file. It seems very simple, that is why I was
wondering if someone could point me in the write direction or could
supply me with a Perl Script that is already out there. Anything
would be much apperciated. Thanks
 
R

Ragnar Hafstað

Clifford Bracht said:
I'm a newbie with Perl Scripts and I need to write a small script. I
have a File that is constently being monitored, and I would like to
create a script that would notify me whenever there is any change at
all made to that file.

if checking the datestamp of the file is enough then
you might want to use -M or stat()

also, what do you mean by 'notify you' ?

gnari
 
E

Erik Tank

I don't know of a script but sound like all you need to do is compare
the last acess date. Check out:
perldoc -f -C
 
J

James Willmore

On 30 Dec 2003 13:54:03 -0800
I'm a newbie with Perl Scripts and I need to write a small script.
I have a File that is constently being monitored, and I would like
to create a script that would notify me whenever there is any change
at all made to that file. It seems very simple, that is why I was
wondering if someone could point me in the write direction or could
supply me with a Perl Script that is already out there. Anything
would be much apperciated. Thanks

Depends. If you want to do something like 'tail -f name_of_file',
there is the File::Tail module. If you want to do something like
'diff -c name_of_file name_of_file.1', there is the Text::Diff module.

I'm sure others have other ways, but this is what I have to offer
based upon what you posted.

HTH

--
Jim

Copyright notice: all code written by the author in this post is
released under the GPL. http://www.gnu.org/licenses/gpl.txt
for more information.

a fortune quote ...
Any sufficiently advanced bug is indistinguishable from a
<feature. -- Rich Kulawiec
 
C

Clifford Bracht

Ragnar Hafstað said:
if checking the datestamp of the file is enough then
you might want to use -M or stat()

also, what do you mean by 'notify you' ?

gnari

Thanks this is a huge help in pointing me in the right direction. As
far as means of notification go I'm not real sure what my choices are.
It would be great to be emailed each time that the file has changed,
but I wasn't sure if it was possible to run a cron job on the file
with the script or not in order for the perl script to constantly .
Do you know what my best bet would be?


Clifford
 
T

Tad McClellan

Clifford Bracht said:
I wasn't sure if it was possible to run a cron job on the file
with the script or not in order for the perl script to constantly .


Huh?
 
C

Clifford Bracht


Sorry after reading that I just realized that it doesn't make any
since at all. The script that I have put together so far works in the
sense that if I add text to the document it notifies me with a message
when I run the script. But what I can't figure out is how to keep the
script running either automatically in so many second intervals or at
all times, so that I don't have to manually run the script to find out
if the file has been modified. Right now I have just a simple print
message to notify the user of a change in the file, but I would like
to email that message instead but I can't figure out how to in
Windows. Here is my code: Does anyone have any suggestions?? Thanks

use File::stat;

$filename = "C:/temp/test.txt";
#converts the epoch time into a readable format.
$orgtime = localtime($^T);

open (FILEHANDLE, "$filename") or die ("Cannot open test.txt");

while (<FILEHANDLE>)
{
#Checks to see what the last modification time since the epoch
is
$modfile = localtime($^T);
$modfile = (stat("$filename"))[9];
#Compares the mtime vs against the orginal epoch
if ($modfile eq $orgtime)
{
print ("File has not changed \n");
}
else
{
print ("Attention n\")
print ("$filename has been modified! n\")


# I want to send a short email here but don't know
how
# to go about it.

}
}
 
T

Tad McClellan

The script that I have put together so far works in the
sense that if I add text to the document it notifies me with a message
when I run the script. But what I can't figure out is how to keep the
script running either automatically in so many second intervals


That is an Operating System question, not a programming language
question. The answer will be the same whether you are using Perl
or Python or C.

or at
all times,


perldoc -q daemon

How do I fork a daemon process?

so that I don't have to manually run the script to find out
if the file has been modified. Right now I have just a simple print
message to notify the user of a change in the file, but I would like
to email that message instead but I can't figure out how to in
Windows.


perldoc -q mail

How do I send mail?

Here is my code: Does anyone have any suggestions??


I'll do a free code review if it has warnings and strictures enabled.

Make your code "use warnings" and "use strict" clean, and post it
again and I'd be happy to look at it for you. Leave those off,
and you are on your own.

open (FILEHANDLE, "$filename") or die ("Cannot open test.txt");
^ ^
^ ^ a useless use of double quotes

perldoc -q vars

What's wrong with always quoting "$vars"?

You should include the $! variable in your die() message, it will
tell you _why_ the open() failed.

if ($modfile eq $orgtime)


Wrong operator. The times are numbers, so you should use a
numeric comparison operator:

if ($modfile == $orgtime)
 
C

Clifford Bracht

Wrong operator. The times are numbers, so you should use a
numeric comparison operator:

if ($modfile == $orgtime)

Here is my code again with the use of strict and warnings. I have
tried to use the statement:

if ($modfile == $orgtime)

But I get an error message saying that the argument isn't numerical
data and that I need to use eq. And I think that is because I changed
the format of $modfile and $orgtime to "localtime" so that it read in
as a string date and time reference.

#!/usr/bin/perl -w
use strict;
use File::stat;


#need to set $filename equal to the file that is being monitored
my $filename = "C:/temp/test.txt";
#converts the epoch time into a readable format.
my $orgtime = ($^T);

open FILEHANDLE, $filename or die "Cannot open $filename,
err=\"$!\"\n";

while (<FILEHANDLE>)
{
#Sets the epoch time inot a readalbe format

#Checks to see what the last modification time since the epoch
is
(my $mtime,) = stat($filename);
$mtime = localtime;

#Compares the mtime vs against the orginal epoch
if ($mtime == $orgtime)
{
print ("$filename has not changed \n");

}
else
{
print ("Attention! \n");
print ("$filename has been modified on $mtime \n");
}

# set the oringal epoch time to = the new modified
time.
# This doesn't work though and I can't figure out why.
$orgtime = $mtime;
}
print ("Done. \n");
close (FILEHANDLE)

Right now it works and tells me that the file has been modified. But I
can't figure out how to reset the orginal epoch time ($orgtime) to =
the time after the "Attention file has been modified message" has been
sent so that when it loops back through it can tell what is just old
modifications that have already been picked up on and what are new
changes to the file. Does that make sense?
Thanks so much for looking at this!
 
T

Tad McClellan

[ attribution missing, please learn to quote followups properly ]

But I get an error message saying that the argument isn't numerical
data and that I need to use eq.


Another alternative is to ensure that it _is_ numerical.

I believe that to be the correct alternative.

And I think that is because I changed
the format of $modfile and $orgtime to "localtime" so that it read in
as a string date and time reference.


You made it a string rather than a number yourself.

Why did you do that?

#converts the epoch time into a readable format.
my $orgtime = ($^T);


That code does not convert the epoch time into a readable format...

It stores into $orgtime the time (in epoch seconds) that your
program began execution.

(my $mtime,) = stat($filename);


That does NOT put the file's modification time into $mtime you know.

I don't see much advantage to using File::stat, I'd just use
the built-in stat() and a "list slice":

my $mtime = (stat($filename))[9];

This change (and removing the localtime()) should fix your problem.

$mtime = localtime;


Since you are going to immediately stomp over that value anyway,
there isn't much point in using stat() at all.. .

localtime() with no args returns the _current_ time, not the
timestamp from the file.

# This doesn't work though and I can't figure out why.
$orgtime = $mtime;


Because $orgtime is a number and $mtime is a string.

localtime()ing $mtime broke things (so don't do that).


Right now it works


I kinda doubt that, since it does not access the modification time
anywhere in the code...
 
B

Brian McCauley

That is an Operating System question, not a programming language
question. The answer will be the same whether you are using Perl
or Python or C.

I think that's a little unfair.

Clearly the question "does my OS have file change notification?" is an
OS question.

Having got the answer to the OS question then the next questions are
"Is there a module (or whatever) for my language to inferface to the
relevant bit of the OS" and "Is there a module that abstracts out the
OS differences and provides a consistant API over all OSs that have
the feature".

From The OP's OS appears to be Win32.

Win32 does have file change notification.

There is a Perl module to interface to Win32's file change
notification mechanism.

IIRC it has 'Win32', 'Change' and 'Notify' in its name.

I'm not aware of any published module that abstracts out the OS
dependancy of file change notification.

--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top