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

I have a file find that works in my Unix but was wondering how I can put a message saying what Directories it could not do a search in? If I am able to search 100 directories from my start directory I would like to know which directories I did not have permissions to search.
use strict; use File::Find; my$startDir = shift || '.'; unless (-d $startDir) { die "Directory '$startDir' is not a Directory.\n"; } find(\&processSub, $startDir); sub processSub { print "Found $File::Find::name\n"; } print "Directories I could not search:\n"; #listing of Unix directories I dont have permissions to search

Replies are listed 'Best First'.
Re: opendir in file find
by skyknight (Hermit) on Jul 25, 2003 at 16:53 UTC

    Basically you want to ask the question "is this file a directory, and is this file not readable to me?" You can accomplish this with two file test operators...

    "doh! can't read directory $file!\n" if (-d $file and not -r $file);
    Update: Slight correction, I think... I believe archon and I were both only half right. You'll want to use both the -r and -x file test operators, at least, based upon what your desire to "search" the directory, this is probably what you want.

      You can save a little overhead by reusing the stat buffer using the magical filehandle '_',

      "doh! can't read directory $file!\n" if (-d $file and not -r _);

      In the case of File::Find, they guarentee that lstat will have been called before the wanted sub is called, so rather than

      sub wanted{ print $File::Find::name if -d $_ and $r $_; }

      you can use

      sub wanted{ print $File::Find::name if -d _ and -r _; }

      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller

        You can save a little overhead by reusing the stat buffer using the magical filehandle '_',

        Yes and no. You can do that if you first disable File::Find's overeager "optimization" via:

        $File::Find::dont_use_nlink= 1;
        If you don't do that first, then File::Find will skip doing lstat in some cases and your use of _ will give you stale data (data for the wrong file) in those cases.

        I'd much rather you have to request this optimization when you want it (which, on some file systems, can speed up Find operations where you don't care about anything but the file name), but p5p seems pretty violently against making this "optimization" opt-in instead of opt-out.

                        - tye

        Way cool. I have never before come across said magical file handle in my travels. I shall have to remember that bit of Perl arcana, though admittedly we might be willfully trading code comprensibility for performance. Of course, in this scenario it may result in our statting each file one third as many times as we may otherwise have, so if we're blasting through a directory structure of thousands of files it will be well worth it.

Re: opendir in file find
by dga (Hermit) on Jul 25, 2003 at 17:14 UTC

    Directory Permissions

    On Linux it works like so:

    I have the following structure x/y/z where z is a file and x and y are directories.

    dr--r--r--: This allows listing x and seeing y but y cannot have stat called on it so nothing can be determined about it. y cannot be listed.

    d--x--x--x: This allows y to be listed if you already know that it is there. x cannot be listed. You can chdir to x.

    dr-xr-xr-x: x can be listed and chdir'ed to y is fully functional.

    So I would say that for a directory to be useable from the standpoint of File::Find that read (-r) and execute (-x) will probably both be needed on a directory in question.

Re: opendir in file find
by archon (Monk) on Jul 25, 2003 at 16:53 UTC
    Just use the -x test on the directory. You can store the ones that fail in an array for the listing later.

      I don't think that is the question he was asking... I was under the impression that by being able to "search" a directory, he meant being able to list its contents. Having execute permissions on a directory makes you able to "cd" through a directory, but does not let you list its contents. As such, a more appropriate test is being able to read the directory, and thus the file test operator he wants is -r.