Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Using File::Find to find drive (Win32)

by FireBird34 (Pilgrim)
on Oct 23, 2003 at 20:41 UTC ( [id://301710]=perlquestion: print w/replies, xml ) Need Help??

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

Given something like:
#!/usr/bin/perl use File::Find; find(\&wanted, "Perl", "/");
How would I get $File::Find::dir to return the drive in which 'Perl' is found? Or better yet, manipulate the find() syntax, so that find() will locate 'Perl', reguardless what drive it's located in (but still return the drive letter)? Any help is appreciated.

Replies are listed 'Best First'.
Re: Using File::Find to find drive (Win32)
by idsfa (Vicar) on Oct 23, 2003 at 21:23 UTC

    If you're not married to File::Find...

    use Config; print $Config{prefix},$/;

    assuming that by 'Perl' you mean the directory where your perl was installed. If you mean the binary, use the perlpath key instead. pod

    Updated:
    You cannot rely upon ^X, because you are assuming certain builds of perl when you do so. CygWin acts as Unix:

    $ uname CYGWIN_NT-5.0 $ perl -e 'print $^X,$/;' perl $ /usr/bin/perl -e 'print $^X,$/;' /usr/bin/perl

    (Thanks to tye and bart for clarifying which perls show this behaviour.)


    Remember, when you stare long into the abyss, you could have been home eating ice cream.
      That still sounds a bit too hard to me. Why not just examine $^X? This command line:
      perl -le "print $^X"
      which, for me, prints
      D:\programs\indigoperl\bin\perl.exe
      
      so it doesn't just copy the name you called perl with, off the command line.
Re: Using File::Find to find drive (Win32) (how)
by tye (Sage) on Oct 23, 2003 at 21:25 UTC

    If you just want to find the location of the Perl.exe that is being run, then ( in Windows, unlike in some, inferior operating systems like Unix :) just check $^X which will always contain the full path to the Perl.exe that is being used.

    (Update: Note that the above method is very reliable, not relying on somewhat optional aspects of the Perl installation. It uses a feature built directly into the Perl executable and a feature built into the Windows operating system. For example, you can move your Perl installation and it will work quite nicely (so long as Perl.exe can be found) for almost all tasks even if you didn't update Config.pm with the new locations. Or you could have a distribution of Perl not from ActiveState or have two versions installed and not be using the one recorded in the registry.)

    (Update: However, it does rely on you not having crippled your "Windows Perl" by actually using Cygwin Perl, as idsfa notes.)

    [Update: If you want to get the root directory of the Perl installation, you can use File::Basename's basename() twice on $^X. If you just want the drive letter, then you can even use the first value returned by File::Spec's splitpath().]

    If you want to search for something named "Perl" that might not be related to the instance of Perl that you are using, then you can use File::Find or other modules and pass it a list of disk drives from Win32API::File:

    use Win32API::File qw( getLogicalDrives GetDriveType DRIVE_FIXED ); use File::Find qw( find ); find( sub { print $File::Find::name,$/ if "perl" eq lc($_); }, grep( DRIVE_FIXED == GetDriveType($_), getLogicalDrives(), ), );

                    - tye
Re: Using File::Find to find drive (Win32)
by bart (Canon) on Oct 23, 2003 at 21:25 UTC
    Is that Windows? It can't work: "/" is the root of the current drive. What you should do, is pass a list of all the roots of all drives to find(). Looking up some Win32 API docs... I found this function:
    use Win32::API; my $GetLogicalDriveStrings = new Win32::API(kernel32 => GetLogicalDriv +eStrings => ['N', 'P'], 'N'); my $drives = "\0" x 4000; my @drives; if($GetLogicalDriveStrings->Call(length $drives, $drives)) { @drives = split /\0+/, $drives; }
    which produces a nice list of drive root directories, with a trailing backslash. Nice.

    You might want to skip the floppies, though... 'A:' and 'B:'. There's an API call to recognize ejectable drives, but I'll skip that for now.

    Now we have a list of roots to scan into, we still have to actually do it:

    use File::Find; my %results; find sub { -f and push @{$results{$File::Find::dir}}, $_ if -e && /^pe +rl/ }, @drives; use Data::Dumper; print Dumper \%results;
    The result of everything found is in a hash. The directory itself will be the hash key, the files found will be in the array that is the hash value.

    update: warning: this takes ages for me to do its job. Don't use it on a regular basis. :)

Re: Using File::Find to find drive (Win32)
by monktim (Friar) on Oct 23, 2003 at 21:12 UTC
    There could be more than one Perl directory. Also, it might not be named Perl. You'd be best off checking the registry to find that out.
    <code> use strict; use warnings; my $Registry; use Win32::TieRegistry( TiedRef => \$Registry ); my $CurrVer = $Registry->{"HKEY_LOCAL_MACHINE\\SOFTWARE\\ActiveState\\ +ActivePerl\\806\\" }; print $CurrVer->{'\\'}."\n";
Re: Using File::Find to find drive (Win32)
by ChrisS (Monk) on Oct 24, 2003 at 12:24 UTC
    I wouldn't use File::Find, I'd try File::Which.
    use File::Which qw(which where); my $exe_path = which('perl'); # or my @paths = where('perl'); $drive_letter = substr($exe_path,0,1); print $drive_letter, "\n"; print $exe_path, "\n"; print join "\n", @paths;
Re: Using File::Find to find drive (Win32)
by FireBird34 (Pilgrim) on Oct 24, 2003 at 17:55 UTC
    Thanks to all! Never even knew about $^X =/ Time to brush up it seems heh. I'll take a look at all the examples and see what one works best for my situation. Again, thanks to all!

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (3)
As of 2024-04-16 11:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found