Syntax Problem...

Discussion in 'Perl Misc' started by Clifford Bracht, Jan 8, 2004.

  1. I'm tring to write a script that verifies if the time of the last
    modification is more recent than the time of the last access. Because
    I would like to know when any action (save, add text, delete text
    etc.) has occurred to the file. But I think that I have some syntax
    problems with either my if statement or the stat function becuase my
    atime and mtime are the same number no matter what kind of changes I
    make to the file. Do any of you guys have any solutions or advice
    for what I have here:
    Thanks in Advance

    #!/usr/bin/perl -w
    #perl -w

    use strict;

    my $filename = "C:/temp/test.txt";

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

    #While file is open do the following...
    while (<FILEHANDLE>)
    {
    #Assign $atime to access time & $mtime to modification time
    #$atime and $mtime are refreshed after each time the info is gathered.

    my $atime = (stat ($filename))[8] || die "Sorry, cannot stat! \n";
    my $mtime = (stat ($filename))[9] || die "Sorry, cannot stat! \n";

    #test output to see what is that is going to be compared.
    print "$atime \n";
    print "$mtime \n";

    #Check to see if modification time is more recent then the time of
    last access.
    if ($mtime == $atime) #$mtime = $ctime)
    {
    print "$filename is OK! \n";
    }
    else
    {
    print "$filename has been modified. \n";
    }
    }
    close FILEHANDLE;
    print "$filename is done testing. \n";
     
    Clifford Bracht, Jan 8, 2004
    #1
    1. Advertising

  2. Clifford Bracht

    gnari Guest

    "Clifford Bracht" <> wrote in message
    news:...

    [snip]

    > #While file is open do the following...
    > while (<FILEHANDLE>)
    > {


    your comment is misleading, i hope this is not your understanding
    of what is happening

    ....
    > my $atime = (stat ($filename))[8] || die "Sorry, cannot stat! \n";
    > my $mtime = (stat ($filename))[9] || die "Sorry, cannot stat! \n";


    maybe your filingsystem does not support both these fields.

    gnari
     
    gnari, Jan 8, 2004
    #2
    1. Advertising

  3. Clifford Bracht <> wrote:

    > I'm tring to write a script that verifies if the time of the last
    > modification is more recent than the time of the last access.



    A modification _is_ an access, _both_ timestamps are updated.

    This has nothing to do with Perl.


    > my
    > atime and mtime are the same number no matter what kind of changes I
    > make to the file.



    That is how it is supposed to be right after the modification.

    Are they different when you do a access (non-modifying) between
    the modification and your Perl program?


    > open FILEHANDLE, $filename or die "Cannot open $filename,



    Why are you open()ing the file?

    You do not need to open the file to examine its timestamps.


    > #While file is open do the following...



    That comment is misleading.

    The file will _still_ be open, even after the while()
    condition becomes false.

    # while there are lines left in the file

    Except now it repeats what is already said in the code, a sign
    that it is a "bad" comment.


    > while (<FILEHANDLE>)



    Why are you looping through all the lines in the file?

    You never use them in your program.


    > my $atime = (stat ($filename))[8] || die "Sorry, cannot stat! \n";
    > my $mtime = (stat ($filename))[9] || die "Sorry, cannot stat! \n";


    my($atime, $mtime) = (stat $filename)[8] || die "Sorry, cannot stat! \n";


    > if ($mtime == $atime) #$mtime = $ctime)



    Huh?

    What were you hoping that that line of code would do?


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Jan 9, 2004
    #3
  4. "Clifford Bracht" <> wrote in message
    news:...
    > I'm tring to write a script that verifies if the time of the last
    > modification is more recent than the time of the last access.


    <snip code>

    Why are you opening the file and reading through it?

    Try using the file test operators ("perldoc -f -X" for more info)

    e.g.

    my $filename = shift;
    my $modified = -C $filename;
    my $accessed = -A $filename;

    print "Modified $modified\nAccessed $accessed\n";

    Paul
     
    Paul Boardman, Jan 9, 2004
    #4
  5. I myself <> wrote:
    > Clifford Bracht <> wrote:



    >> my $atime = (stat ($filename))[8] || die "Sorry, cannot stat! \n";
    >> my $mtime = (stat ($filename))[9] || die "Sorry, cannot stat! \n";

    >
    > my($atime, $mtime) = (stat $filename)[8] || die "Sorry, cannot stat! \n";



    Errr, make that:

    my($atime, $mtime) = (stat $filename)[8,9] || die "Sorry, cannot stat! \n";


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Jan 9, 2004
    #5
  6. "Paul Boardman" <> wrote in message news:<>...
    > "Clifford Bracht" <> wrote in message
    > news:...
    > > I'm tring to write a script that verifies if the time of the last
    > > modification is more recent than the time of the last access.

    >
    > <snip code>
    >
    >> Why are you opening the file and reading through it?

    >
    >

    First off, Thank you to everyone for the suggestions and help.
    I figured out a few of my mistakes shortly after I posted my message
    and after working on the coding some I have come up with this:

    #!/usr/bin/perl -w
    #perl -w
    $filename = "C:/temp/test.txt";
    Set_File();

    sub Set_File
    {

    open (FILEHANDLE, "<$filename") || die "Cannot open $filename,
    err=\"$!\"\n";

    if ($filename ne " \n")
    {
    $mtime = (stat ($filename))[9] || die "Sorry, cannot stat! \n";
    Check_Mod();
    }
    }

    sub Check_Mod
    {
    while(1)
    {
    $mtime_2 = (stat ($filename))[9] || die "Sorry, cannot stat! \n";

    #View the two Mod times for test purposes.
    print "previous_mtime = $mtime and mtime = $mtime_2 \n";

    #Test to see if Modification have been made to file
    if ($mtime_2 ne $mtime)
    {
    print "$filename has been modified.! \n";
    Set_File();
    }
    else
    {
    print "$filename is OK. \n";
    }

    print "$filename is done testing. \n";
    #sleep 60;
    }
    }

    I have tested it and when I change the file it sends the correct
    message and then runs through a new loop.

    But it runs in an infinite loop that I would only like to run every 60
    seconds, but when I put the code the line:
    sleep 60; the script will not output anything??? Does anyone have any
    suggestions. Do I have the sleep function in the correct place, or do
    I need to go about this in a differe way??

    I also don't know if I used proper Perl practices by calling the sub
    routines the way that I did at the beginning and in the while loop, so
    that might contribute to the problem?? Thanks
     
    Clifford Bracht, Jan 9, 2004
    #6
  7. Clifford Bracht

    J. Gleixner Guest

    Clifford Bracht wrote:
    > "Paul Boardman" <> wrote in message news:<>...
    >
    >>"Clifford Bracht" <> wrote in message
    >>news:...
    >>
    >>>I'm tring to write a script that verifies if the time of the last
    >>>modification is more recent than the time of the last access.

    >>
    >><snip code>
    >>
    >>>Why are you opening the file and reading through it?

    >>
    >>

    > First off, Thank you to everyone for the suggestions and help.
    > I figured out a few of my mistakes shortly after I posted my message
    > and after working on the coding some I have come up with this:
    >
    > #!/usr/bin/perl -w
    > #perl -w
    > $filename = "C:/temp/test.txt";

    my $filename = 'C:/temp/test.txt';
    my $mtime;
    > Set_File();
    >
    > sub Set_File
    > {
    >
    > open (FILEHANDLE, "<$filename") || die "Cannot open $filename,
    > err=\"$!\"\n";


    Again, as others have said and you have included in this post, you don't
    need to.. or to make it clear DON'T open the file. You're not reading
    the contents within the file, so don't open it.

    You can use "-f" to see if the file exists.

    >
    > if ($filename ne " \n")
    > {
    > $mtime = (stat ($filename))[9] || die "Sorry, cannot stat! \n";
    > Check_Mod();
    > }
    > }


    Your subroutine could simply be replaced by:

    die "$filename doesn't exist." if !-f $filename;
    my $mtime = (stat ($filename))[9] || die "..."

    Also, if you want to use subroutines, get in the habit of passing things
    to them and not relying on global variables.

    Set_file($filename); #is Set_file a good name for this sub??
    Check_mod($filename);

    sub Set_File
    {
    my $fname = shift;
    ..blah..
    }
    sub Check_Mod
    {
    my $fname = shift;
    ...blah blah blah...
    }

    >
    > sub Check_Mod
    > {
    > while(1)
    > {
    > $mtime_2 = (stat ($filename))[9] || die "Sorry, cannot stat! \n";


    Can't stat what?? or why??.. include $filename and $! in your error message.

    my $mtime_2 = (stat ($filename))[9] || die "Sorry, cannot stat
    $filename: $! \n";

    >
    > #View the two Mod times for test purposes.
    > print "previous_mtime = $mtime and mtime = $mtime_2 \n";
    >
    > #Test to see if Modification have been made to file
    > if ($mtime_2 ne $mtime)

    Although it doesn't affect the result, since mtime and mtime_2 are
    integers, you should use integer's equality (==).

    > {
    > print "$filename has been modified.! \n";
    > Set_File();


    There's no need to call Set_file, you already have the new modification
    time in mtime_2, just update your mtime variable;

    print "$filename has been modified.! \n";
    $mtime = $mtime2;
    > }
    > else
    > {
    > print "$filename is OK. \n";
    > }
    >
    > print "$filename is done testing. \n";
    > #sleep 60;
    > }
    > }
    >
    > I have tested it and when I change the file it sends the correct
    > message and then runs through a new loop.
    >
    > But it runs in an infinite loop that I would only like to run every 60
    > seconds, but when I put the code the line:
    > sleep 60; the script will not output anything??? Does anyone have any
    > suggestions. Do I have the sleep function in the correct place, or do
    > I need to go about this in a differe way??


    Well, you'd need to wait for up to 60 seconds after the file is modified
    before it'd print anything.

    It's probably best to examine why you need to know that the file's
    modification time has changed and how often you should check it. The
    longer can wait to poll the file, the better. Usually find (man find or
    perldoc File::Find) is a common method of finding out if a file has been
    modified in the past number of seconds, hours, days.

    >
    > I also don't know if I used proper Perl practices by calling the sub
    > routines the way that I did at the beginning and in the while loop, so
    > that might contribute to the problem?? Thanks


    You called them correctly, however the call in the while() wasn't needed
    and using them at all wasn't really needed. In your example, the code is
    so short that using subroutines doesn't help or hurt. If you're
    learning about subroutines, then by all means use them a lot, and get
    used to passing information to them and returning information from them.
    After a while you'll determine when it's best to/not to use them.
     
    J. Gleixner, Jan 9, 2004
    #7
  8. Clifford Bracht <> wrote:
    > "Paul Boardman" <> wrote in message news:<>...
    >> "Clifford Bracht" <> wrote in message
    >> news:...
    >> > I'm tring to write a script that verifies if the time of the last
    >> > modification is more recent than the time of the last access.

    >>
    >> <snip code>
    >>
    >>> Why are you opening the file and reading through it?

    >>
    >>

    > First off, Thank you to everyone for the suggestions and help.



    But you are not going to answer the question that you were asked?

    I don't think it was a rhetorical question.

    It appears that you have a profound misunderstanding somewhere and
    the answer to the question will help us figure out where you went
    wrong so that we can help you.


    > $filename = "C:/temp/test.txt";



    > open (FILEHANDLE, "<$filename") || die "Cannot open $filename,
    > err=\"$!\"\n";



    Why are you open()ing the file?

    You do not need to open() the file!


    > if ($filename ne " \n")



    Why is this test here?

    How is it that you expect to have that value in $filename?

    It is hardcoded above and never changed as far as I can see...


    > #Test to see if Modification have been made to file
    > if ($mtime_2 ne $mtime)



    That is not the right test.

    ne is for comparing strings, != is for comparing numbers, you have numbers:

    if ($mtime_2 != $mtime)


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Jan 9, 2004
    #8
  9. Clifford Bracht

    J. Gleixner Guest


    > Although it doesn't affect the result, since mtime and mtime_2 are
    > integers, you should use integer's equality (==).


    I meant inequality.. (!=)
     
    J. Gleixner, Jan 9, 2004
    #9
  10. Clifford Bracht

    Tore Aursand Guest

    On Thu, 08 Jan 2004 12:24:47 -0800, Clifford Bracht wrote:
    > I'm tring to write a script that verifies if the time of the last
    > modification is more recent than the time of the last access. Because
    > I would like to know when any action (save, add text, delete text
    > etc.) has occurred to the file. But I think that I have some syntax
    > problems with either my if statement or the stat function becuase my
    > atime and mtime are the same number no matter what kind of changes I
    > make to the file.


    You have a problem with the logic here; If you change a file _both_ the
    access time _and_ the modification time of that file will be changed (to
    the same value).

    You have to access a file when modifying it, right?

    Based on this, you should create a script which runs forever (...) and
    does something if the current modification time is different from the
    previous modification time.

    Something like this should get you going (untested):

    #!/usr/bin/perl
    #
    use strict;
    use warnings;

    my $filename = 'test.txt';
    unless ( -e $filename ) {
    die "The file '$filename' doesn't exist!\n";
    }

    my $sleep = 2; # How many seconds to sleep() between each test
    my $prev_mtime = 0; # Previous modification time

    while ( 1 ) {
    my $mtime = ( stat($filename) )[9];
    if ( $prev_mtime != 0 && $prev_mtime != $mtime ) {
    # File has been modified
    }
    $prev_mtime = $mtime;
    sleep( $sleep );
    }


    --
    Tore Aursand <>
    "Nothing is certain but death and taxes. Of the two, taxes happen
    annually." -- Joel Fox
     
    Tore Aursand, Jan 10, 2004
    #10
  11. Tore Aursand <> wrote in message news:<>...
    >
    >> You have a problem with the logic here; If you change a file

    _both_ the
    >> access time _and_ the modification time of that file will be

    changed (to
    >> the same value).
    >>
    >> You have to access a file when modifying it, right?
    >>
    >> Based on this, you should create a script which runs forever (...)

    and
    >> does something if the current modification time is different from

    the
    >> previous modification time.
    >>
    >> Something like this should get you going (untested):


    With the use of your script along with some added code to enable the
    sending of an email notification I got it working the way that I would
    like. I thought that I would post the final script for future
    reference in case anyone would ever need a similar script. Again
    thanks to everyone that took the time to often suggestions, code and
    point out where and what I was doing wrong.

    #!/usr/bin/perl

    use strict;
    use warnings;
    use Mail::Sender;

    #Need to change the file path to the file or address that you want to
    monitor
    my $filename = "c:/temp/test.txt";

    unless ( -e $filename )
    {
    die "The file '$filename' doesn't exist!\n";
    }

    my $sleep = 60; # How many seconds to sleep() between each
    test
    my $prev_mtime = 0; # Previous modification time

    while ( 1 )
    {
    my $mtime = ( stat($filename) )[9];
    if ($prev_mtime != 0 && $prev_mtime != $mtime )
    {
    my $to = '';
    my $from = '';
    my $smtpServer = 'Smtpserver.com';
    my $sender = new Mail::Sender
    {
    smtp => $smtpServer, from => $from,};
    $sender->MailMsg({to => $to, subject => 'File has been
    modified.',
    msg => "The File that you have been monitoring has been
    modified!",
    file => 'c:\temp\test.txt'}) or die "$Mail::Sender::Error\n";


    }
    $prev_mtime = $mtime;
    sleep( $sleep );
    }
     
    Clifford Bracht, Jan 12, 2004
    #11
  12. Clifford Bracht

    Ben Morrow Guest

    (Clifford Bracht) wrote:
    > #!/usr/bin/perl
    >
    > use strict;
    > use warnings;
    > use Mail::Sender;
    >
    > #Need to change the file path to the file or address that you want to
    > monitor
    > my $filename = "c:/temp/test.txt";
    >
    > unless ( -e $filename )
    > {
    > die "The file '$filename' doesn't exist!\n";
    > }


    I would move this test inside the loop, in case someone deletes it
    while you are running.

    I would also write it as

    -e $filename or die "...";

    but that's a matter of style rather than correctness.

    >
    > my $sleep = 60; # How many seconds to sleep() between each
    > test
    > my $prev_mtime = 0; # Previous modification time
    >
    > while ( 1 )
    > {

    <snip>

    --
    don't get my sympathy hanging out the 15th floor. you've changed the locks 3
    times, he still comes reeling though the door, and soon he'll get to you, teach
    you how to get to purest hell. you do it to yourself and that's what really
    hurts is you do it to yourself just you, you and noone else *
     
    Ben Morrow, Jan 12, 2004
    #12
    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. gabriele renzi
    Replies:
    2
    Views:
    221
    gabriele renzi
    Dec 31, 2005
  2. Ken Bloom
    Replies:
    3
    Views:
    224
  3. Good Night Moon
    Replies:
    9
    Views:
    294
    Rick DeNatale
    Jul 25, 2007
  4. Jacob Grover
    Replies:
    5
    Views:
    327
    Jacob Grover
    Jul 18, 2008
  5. Mark Richards
    Replies:
    3
    Views:
    324
    Tad McClellan
    Nov 18, 2007
Loading...

Share This Page