Monitoring File Changes

Discussion in 'Perl Misc' started by Clifford Bracht, Dec 30, 2003.

  1. 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
    Clifford Bracht, Dec 30, 2003
    #1
    1. Advertising

  2. "Clifford Bracht" <> wrote in message
    news:...
    > 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
    Ragnar Hafstað, Dec 30, 2003
    #2
    1. Advertising

  3. Clifford Bracht

    Erik Tank Guest

    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

    On 30 Dec 2003 13:54:03 -0800, (Clifford
    Bracht) wrote:

    >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
    Erik Tank, Dec 30, 2003
    #3
  4. On 30 Dec 2003 13:54:03 -0800
    (Clifford Bracht) wrote:

    > 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
    James Willmore, Dec 31, 2003
    #4
  5. "Ragnar Hafstað" <> wrote in message news:<bsssoq$bbi$>...
    > "Clifford Bracht" <> wrote in message
    > news:...
    > > 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


    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
    Clifford Bracht, Dec 31, 2003
    #5
  6. Clifford Bracht <> wrote:

    > 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?


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Dec 31, 2003
    #6
  7. (Tad McClellan) wrote in message news:<>...
    > Clifford Bracht <> wrote:
    >
    > > 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?


    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.

    }
    }
    Clifford Bracht, Dec 31, 2003
    #7
  8. Clifford Bracht <> wrote:


    > 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)


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Dec 31, 2003
    #8
  9. >
    > > if ($modfile eq $orgtime)

    >
    >
    > 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!
    Clifford Bracht, Jan 2, 2004
    #9
  10. Clifford Bracht <> wrote:

    [ attribution missing, please learn to quote followups properly ]


    >> Wrong operator. The times are numbers, so you should use a
    >> numeric comparison operator:
    >>
    >> if ($modfile == $orgtime)


    > 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...


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Jan 2, 2004
    #10
  11. (Tad McClellan) writes:

    > Clifford Bracht <> wrote:
    >
    >
    > > 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.


    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\\
    Brian McCauley, Jan 2, 2004
    #11
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Carl Prothman [MVP]
    Replies:
    1
    Views:
    4,219
    Ali_ggl
    Mar 17, 2008
  2. Edward Yang
    Replies:
    1
    Views:
    4,098
    Jose Marcenaro
    Feb 20, 2004
  3. Mark
    Replies:
    7
    Views:
    4,891
  4. Robin
    Replies:
    1
    Views:
    3,028
    JustMe
    Oct 4, 2004
  5. Jay Ge
    Replies:
    5
    Views:
    821
    Karl Seguin
    Nov 17, 2004
Loading...

Share This Page