Syntax Problem...

  • Thread starter Clifford Bracht
  • Start date
C

Clifford Bracht

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";
 
G

gnari

[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
 
T

Tad McClellan

Clifford Bracht said:
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?
 
P

Paul Boardman

Clifford Bracht said:
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
 
T

Tad McClellan

I myself said:
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";
 
C

Clifford Bracht

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
 
J

J. Gleixner

Clifford said:
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.
 
T

Tad McClellan

Clifford Bracht said:
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)
 
T

Tore Aursand

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 );
}
 
C

Clifford Bracht

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 = '(e-mail address removed)';
my $from = '(e-mail address removed)';
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 );
}
 
B

Ben Morrow

#!/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>
 

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,754
Messages
2,569,527
Members
44,998
Latest member
MarissaEub

Latest Threads

Top