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

OK, I've read through the perldoc on File::Find, and did some searching here as well as via Google, but to no avail. I'm guessing I'm missing something fairly fundamental here, and I'm hoping someone will be kind enough to point out what that is exactly :)

I can't seem to get File::Find to do anything on Win32 (WinNT with latest Activestate release build).

The relevant code snippet from my larger script is as follows:

use File::Find (); $File::Find::dont_use_nlink=1; # I found a post here that said somethi +ng about setting this if you intend to run it on DOS, and I did as I +may want to run it on Win95/98 as well # I'm looking for "eudora.ini" on my system and I want it to search fr +om the root of C: (and it definitely exists on my system) File::Find::find( {wanted => \&wanted}, 'C:/' ) || die "Can't search f +or file: $" ; sub wanted { /^eudora\.ini\z/s; } print ($File::Find::name);

Right now, it doesn't print anything, and my hard drive doesn't spin at all.

I've also tried substituting '/' and 'C:/' instead of 'c:/', but it made no difference.

The rest of my script below the above code works just fine, it's just this piece that's giving me grief :)

Thanks for all suggestions.

Glenn

Replies are listed 'Best First'.
Re: File::Find on Win32 - basic problem/question
by Aristotle (Chancellor) on Oct 02, 2003 at 19:36 UTC
    The File::Find docs for the version shipped with Perl 5.8 say

    $dont_use_nlink

    You shouldn't need to set this variable, since File::Find should now detect such file systems on-the-fly and switch itself to using stat. This works even for parts of your file system, like a mounted CD-ROM.

    You probably want to make your regex case insensitive, as well.

    At any rate, the point is that your wanted function's return value is completely irrelevant to File::Find. $File::Find::name's value after find terminates is not defined either. You have to use your wanted function to store the name, if you want to do so. Something like

    my $found; sub wanted { $found = $File::Find::name if /^eudora\.ini\z/i; }
    You could also try File::Find::Rules which has a much nicer interface for simple cases.
    my ($found) = File::Find::Rule ->file ->name('eudora.ini') ->in('C:\\');

    Makeshifts last the longest.

      OK, thanks, that's clear now. I'm looking into File::Find::Rule, it seems to do what I need it to.

      Thanks,
      Glenn

Re: File::Find on Win32 - basic problem/question
by shenme (Priest) on Oct 02, 2003 at 19:52 UTC
    Here's another example to reinforce Aristotle's point - that you are responsible for capturing the information from matched files.   File::Find is providing the file-system traversal processing, not the processing you must add (into your wanted() ).
    use File::Find (); # and my wanted() routine to stuff names into this list my @things_I_like; File::Find::find( {wanted => \&wanted}, '..' ); sub wanted { # print " We're looking at '$File::Find::name' ... (\$_ is '$_')\ +n"; # push @things_I_like, $_ push @things_I_like, $File::Find::name if m/^mabman1\.pl\z/s; # if m/^spam\.spam\z/s; } if( @things_I_like ) { print " I like @things_I_like\n"; } else { print " Nothing's going my way.\n"; }
    prints
      I like ../test/mabman1.pl
    
Re: File::Find on Win32 - basic problem/question
by bart (Canon) on Oct 02, 2003 at 21:21 UTC
    Try, after correcting your code, with a subdirectory. I do believe File::Find on Windows is broken for the root directory. This works for me:
    my $dir = 'c:/windows'; use File::Find (); File::Find::find( {wanted => \&wanted}, $dir ); sub wanted { print "$File::Find::name\n" if /\.ini\z/s; }
    and it doesn't do a thing when $dir is set to 'c:/'.
      It seems to work form me from the root directory with
      $dir = "/";
      At least on XP! Rob.
Re: File::Find on Win32 - basic problem/question
by NetWallah (Canon) on Oct 02, 2003 at 19:34 UTC
    I think you are missing an "_" (Underscore).
    Your line should read:
    File::Find::find( {wanted => \&wanted}, 'C:/' ) || die "Can't search + for file: $_" ;