Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

strange loopiness with chdir on win2k

by Reverend Phil (Pilgrim)
on Feb 25, 2002 at 20:19 UTC ( [id://147370]=perlquestion: print w/replies, xml ) Need Help??

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

Hi folks. Here's my oddity from Friday, though I couldn't get to our beloved site then.

I'm attempting to recurse through directories, and snag path and file names for anything which hasn't been modified in a certain amount of time. Should be really simple, but I'm getting caught in some infinite loopiness. I'm running this on a Win2K box with the lastest Activestate, and I'm accessing a WinNT server. Here's the code, with ugly debugging hubbub within ##DEBUG## nubs.

use strict; use Cwd; my $age = 365; my %data; my $hits = 0; my $dirs = 0; print "Start Time: ".scalar(localtime)."\n"; my $log = ">C:/perl/scripts/data/log.txt"; my $old_log = ">C:/perl/scripts/data/old_log.txt"; open(OLD, $old_log) or die("Unable to open $old_log:$!\n"); open(LOG, $log) or die("Unable to open $log:$!\n"); print OLD "Directory\tFile Name\tLast Accessed\n"; sub ScanDirectory{ my ($workdir) = shift; my ($startdir) = &cwd; chdir($workdir) or die("Unable to enter working dir $workdir:$!\n" +); unless ( opendir(DIR, ".") ){ chdir($startdir) or die ("Botched completely here in $startdir +<>$workdir $!\n"); print "Unable to open $workdir: $!\n"; return; } my @names = readdir(DIR) or die("Unable to read $workdir:$!\n"); closedir(DIR); ##DEBUG## print LOG "Workdir: $workdir\n"; print LOG "Startdir: $startdir\n"; print LOG "Files:\n",join("\n",@names),"\n"; ##DEBUG## foreach my $name (@names){ ##DEBUG## if($workdir =~ /Problem/){ print LOG "File: $name being checked\n"; } ##DEBUG## next if ($name eq "."); next if ($name eq ".."); $hits++; if (-d $name){ $dirs++; ##DEBUG## print LOG "IN: $workdir FROM: $startdir SCANNING: $name\n"; ##DEBUG## &ScanDirectory($name); next; } my $file_age = int(-M $name); if($file_age > $age){ my $dir = "$startdir/$workdir"; $dir =~ tr/\//\\/; print OLD "$dir\t$name\t$file_age\n"; } chdir($startdir) or die("Unable to change to dir $startdir:$!\ +n"); } } chdir("//server/folder"); &ScanDirectory("."); print "End Time: ", scalar(localtime), "\n"; print "$hits files checked, $dirs of which were Directories\n"; close(OLD);
Now that I've gone and posted the code, I guess I should explain what the problem is. If I have a subdirectory within a subdirectory - and they have the same name - my code seems to think that it changed into that directory, but in truth it starts from scratch in the former directory.

Pardon me if that makes no sense. But it's odd. The ##DEBUG## gump is there so that when it starts looping, I can see where it starts and pull out my hair. Also, the line with /Problem/ is there just to add extra logging when I come across the /Problem/ directory =) Feel free to test this on your own system, changing the server names and your 'problem' folder as well. Please test this on a decent sized directory tree, and try copying a folder and pasting it inside of itself. I tried to reproduce this on the simplest structure (folder a has folder b with additional folder b inside of it) and I had no problem. Perhaps I should post this under Seekers of Sanity, or perhaps another monk may shed some light unto my absurdity.

-=rev=-

Replies are listed 'Best First'.
Re: strange loopiness with chdir on win2k
by chromatic (Archbishop) on Feb 25, 2002 at 20:29 UTC
    When anyone says "recurse through directories", think File::Find:
    use File::Find; use File::Basename; find({ wanted => sub { my $file_age = int(-M $_); if ($file_age > $age) { my ($dir, $path) = fileparse($_); print OLD "$dir\t$name\t$file_age\n"; } }, no_chdir => 1 }, '.');
    That's untested, but it's a little simpler than doing it yourself. :)
(Ovid) Re: strange loopiness with chdir on win2k
by Ovid (Cardinal) on Feb 25, 2002 at 20:58 UTC

    Reverend Phil wrote:

    If I have a subdirectory within a subdirectory - and they have the same name - my code seems to think that it changed into that directory, but in truth it starts from scratch in the former directory.

    File::Find changes directories for you (unless you tell it not to) and is very easy to use. Here's the basic shell of how to use it.

    use strict; use File::Find; my $root_dir = '/temp'; find(\&wanted, $root_dir); sub wanted { if ( -d ) { # you've been 'chdir'ed to this directory print "Directory: $_\n"; } else { # not a directory. do as you will } }

    Cheers,
    Ovid

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (5)
As of 2024-03-29 06:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found