Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Perl process to constantly detect the time change of a file?

by blackcode6 (Novice)
on May 03, 2002 at 20:18 UTC ( [id://163893]=perlquestion: print w/replies, xml ) Need Help??

blackcode6 has asked for the wisdom of the Perl Monks concerning the following question:

Fellow monks, I wrote a small inefficient perl script that checks to see if the time has changed on the /var/log/httpd/access_log file. If the file time is the same it prints a period. Once the file is "touch"ed by anything and the time changes, the script prints an "x". Eventually, I want to move to a specific response instead of an "x". The file uses 12% of cpu process because of its while loop nature. Is there a better way to do this?
#!/usr/bin/perl print "Testing to see if file changes.\n"; $listing = `ls -al access_log`; @fields = split /" "/,$listing; foreach (@fields) { if (/[0-9][0-9]:[0-9][0-9]/) { $status = $&; print "Status is :",$status,"\n"; } else { print "Didn't find anything.\n"; } } @fields = split /:/, $status; $hours = @fields[0]; $minutes = @fields[1]; print "hours :",$hours,"\n"; print "minutes :",$minutes,"\n"; $hours2 = $hours; $minutes2 = $minutes; @fields = (); while (1) { while ($hours == $hours2 && $minutes == $minutes2) { $listing = `ls -al access_log`; @fields = split /" "/,$listing; foreach (@fields) { if (/[0-9][0-9]:[0-9][0-9]/) { $status = $&; } else { # print "Didn't find anything suckker.\n"; } } @fields = split/:/,$status; $hours = @fields[0]; $minutes=@fields[1]; @fields= (); print "."; # meaning the time is the still the same } $hours2 = $hours; $minutes2 = $minutes; print "x"; # meaning the time has changed; file touched }

Replies are listed 'Best First'.
Re: Perl process to constantly detect the time change of a file?
by Rich36 (Chaplain) on May 03, 2002 at 20:33 UTC

    You could cut out a lot of code by using stat - specifically "mtime", which is the "last modify time in seconds since the epoch". I would suggest putting a small sleep time in the loop as well, just so you're not constantly hitting your machine - unless it's absolutely crucial that you know the second when this file has changed.

    my $file = "somefile.txt"; # Establish a base "last accessed time" my $lastaccessed = (stat($file))[9]; while(1) { if ((stat($file))[9] == $lastaccessed) { # The file is the same } else { # File is different } sleep 5; }

    Check the docs for stat - it provides a lot of useful info about files.


    Rich36
    There's more than one way to screw it up...

      Right -- of course one would usually want to make sure it goes like this (Rich36 assumes this goes without saying):
      while(1) { my $modtime = (stat($file))[9]; if ($modtime == $lastaccessed) { # The file is the same } else { # File is different; do whatever, and also: $lastaccessed = $modtime; } sleep 5; }
Re: Perl process to constantly detect the time change of a file?
by stefp (Vicar) on May 04, 2002 at 02:31 UTC
    May be you want first to check out packages that do similar stuff like File::Tail, File::MultiTail and even POE::Wheel::FollowTail if you want to insert you stuff in an event framework. Even when I don't use a package or don't borrow code from it, I sometimes notice they deal with issues I had overlooked.

    -- stefp -- check out TeXmacs wiki

      I think this is an excellent advice as it looks at the problem from a different perspective. Instead of polling the time the file was last changed, you wait for the file to change. (this of course assumes you can read from the file)

      ++stefp++

      Update: Actually, coming to read the original post again, this will not work if the file is "touched" by another process, only if appended to. Nonetheless, --stefp++ :-)

Re: Perl process to constantly detect the time change on a file?
by bluto (Curate) on May 03, 2002 at 20:30 UTC
    To answer your question, use the sleep function in between each iteration. If you only sleep for a second or two each time through, you will save a boat load of cpu time.

    If you can get away with just checking once per minute, and you are on some unix variant, you can run a script via cron.

    On a broader note: This is a very long winded way of doing this. Instead of forking off a process and parsing the output, you can save a lot more CPU time (not to mention coding headaches) by using the stat function and just checking the mtime field.

    bluto

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://163893]
Approved by DaWolf
Front-paged by DaWolf
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (3)
As of 2025-06-14 11:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.