infinite loop to monitor directories

M

mr.vlad.dracula

Do you think you can point me on the right direction?

Desired result: Monitor directories indefinitely, print on screen if a
file found is older than 1 minute. It's supposed to bypass
subdirectories, hidden files/directories as well.

Problem: if a file is there already on any of the directories, it will
print out the file just fine. However, if I delete that file and drop
another one, wait a minute or more, nothing displays. It's not really
going inside the directories after the first time.

Thank you...

#!/usr/bin/perl

use warnings;
use strict;
use File::Find;

my @directories = ("/home/foo/dir1","/home/foo/dir2");
my $MINUTES = 0.0007; #<-1 min expressed in days
my $condition = 1;

#supposedly loops forever
while ($condition == 1){
find(\&process, @directories, no_chdir => 1);
}


sub process {

#only files, not directories. skip . and .. files

if (-f $_ and !/^\./){

if (-M $_ >= $MINUTES){

print "$File::Find::name\n";

}

}

sleep 1;

}
 
A

A. Sinan Unur

(e-mail address removed) wrote in (e-mail address removed):
Do you think you can point me on the right direction?

Desired result: Monitor directories indefinitely, print on screen if a
file found is older than 1 minute. ....

#!/usr/bin/perl

use warnings;
use strict;
use File::Find;

my @directories = ("/home/foo/dir1","/home/foo/dir2");
my $MINUTES = 0.0007; #<-1 min expressed in days

my $condition = 1;

#supposedly loops forever
while ($condition == 1){

while ( 1 ) {

would get rid of the unnecessary variable $condition.
find(\&process, @directories, no_chdir => 1);
}

They syntax of your call is incorrect. From perldoc File::Find:

find
find(\&wanted, @directories);
find(\%options, @directories);

You would have noticed this if you had used some debugging print
statements:

Can't stat no_chdir: No such file or directory
Can't stat 1: No such file or directory

find( { wanted => \&process, no_chdir => 1 }, @directories );
sub process {
#only files, not directories. skip . and .. files
if (-f $_ and !/^\./){
if (-M $_ >= $MINUTES){
print "$File::Find::name\n";

perldoc -f -X

-M Script start time minus file modification time, in days.

Now, the main problem. You have
my $MINUTES = 0.0007; #<-1 min expressed in days

If you create a new file, -M on that file will return a negative number.
You have assigned to $MINUTES a positive number so the condition

-M >= $MINUTES

will never hold for any file created after the script has been started.

Because of this logic error, I am a bit confused about what you really
want. Assuming you mean what you say about files "older than one
minute", you need to compare to current time not to -M.

From perldoc perlvar:

$BASETIME
$^T The time at which the program began running, in seconds since

So, to find the files older than 60 seconds, you would use the
following:

#!/usr/bin/perl

use warnings;
use strict;
use File::Find;

use constant SECONDS_PER_DAY => 24*60*60;

my @directories = ( "$ENV{HOME}/Src/Test" );

while ( 1 ) {
find( { wanted => \&process, no_chdir => 1 }, @directories );
sleep 1;
}

sub process {
return if not -f or /^\./;
my $mtime = -M;
my $age = $^T - $mtime * SECONDS_PER_DAY ;

if ( time - $age > 60 ) {
print "$_ : $age\n";
}
}

__END__


--
A. Sinan Unur <[email protected]>
(remove .invalid and reverse each component for email address)

comp.lang.perl.misc guidelines on the WWW:
http://www.rehabitation.com/clpmisc/
 
D

dracula

I read the documentation for file::find but still a little unclear.

Would this be the only thing I need to skip subdirectories and hidden
files/directories?
find( { wanted => \&process, no_chdir => 1 }, @directories );

If so, then I don't need this line then right?.
return if not -f or /^\./;

please advise and thanks in advance.
:)


<snip>
 
A

A. Sinan Unur

[ Do *not* top-post and do *not* quote messages in full ]
I read the documentation for file::find but still a little unclear.

The module is File::Find. Case matters.
Would this be the only thing I need to skip subdirectories and hidden
files/directories?
find( { wanted => \&process, no_chdir => 1 }, @directories );

Of course not. What gave you that impression.
If so, then I don't need this line then right?.
return if not -f or /^\./;

You do need that line in sub process to skip things that are not plain
files or files whose names begin with a dot.

Sinan

--
A. Sinan Unur <[email protected]>
(remove .invalid and reverse each component for email address)

comp.lang.perl.misc guidelines on the WWW:
http://www.rehabitation.com/clpmisc/
 
B

Ben Morrow

Quoth "A. Sinan Unur said:
If you create a new file, -M on that file will return a negative number.
You have assigned to $MINUTES a positive number so the condition

-M >= $MINUTES

will never hold for any file created after the script has been started.

Because of this logic error, I am a bit confused about what you really
want. Assuming you mean what you say about files "older than one
minute", you need to compare to current time not to -M.

From perldoc perlvar:

$BASETIME
$^T The time at which the program began running, in seconds since

So, to find the files older than 60 seconds, you would use the
following:
my $mtime = -M;
my $age = $^T - $mtime * SECONDS_PER_DAY ;

if ( time - $age > 60 ) {

....or forget both -M and $^T (especially since converting a time to a
float and back probably isn't a good idea) and just use

use File::stat;

if (time - stat($_)->mtime <= 60)

Ben
 

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

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top