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

Suppress 'Can't chdir to' warnings for File::Find

by mabossert (Scribe)
on Apr 28, 2016 at 16:03 UTC ( [id://1161786]=perlquestion: print w/replies, xml ) Need Help??

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

I am writing some prototype code for a larger application that needs to search all directories from a particular starting point and return all directories that contain certain types of files. The function works fine excepts for producing warnings related to not being able to chdir to directories for which the user who runs the application does not have sufficient permissions to read.

Perhaps I am just being pickier than I should, but the application needs to traverse directories that belong to the user and also ones that do not belong to the user, but for which the user has sufficient permissions to read. When I run the test code, everything works as expected, but produces warnings. They are expected, but I would like to suppress them or "tell" File::Find to skip any directories that the user does not have permissions to access. On the other hand, maybe there is a way to tell File::Find to first test if it can read the directory and then move on if it cannot?

Here is my current code. Any suggestions would be greatly appreciated.

#!/usr/bin/env perl use strict; use warnings; use 5.016; use Carp qw(cluck carp croak); use JSON qw( encode_json ); use File::Find; use Data::Dumper; my %seen; my @files; find ({ wanted => \&wanted }, '/mnt/lustre'); say Dumper(\@files); sub wanted { if($File::Find::name =~ /\.nt$|^dbQuads$|^graph.info$|^string_table_ +chars.index$|^string_table_chars$/ && !exists $seen{$File::Find::dir} +) { my $user = (getpwuid ((stat $File::Find::dir)[4]))[0]; my $name = $1 if $File::Find::dir =~ /\/([^\/]+)$/; #=+ Would like to know how big the directory contents are my $raw_size = 0; my $db_size = 0; my $built = 0; find(sub { if(-f $_ && $_ =~ /\.nt$/) { $raw_size += -s $_; } elsif(-f $_ && $_ =~ /^dbQuads$|^string_table_chars.index$|^stri +ng_table_chars$/) { $db_size += -s $_; $built = 1; } },$File::Find::dir); my %temp = ( owner => $user, raw_size => $raw_size, db_size => $db_size, name => $name, path => $File::Find::dir, built => $built ); push @files, \%temp; $seen{$File::Find::dir} = 1; } }

Replies are listed 'Best First'.
Re: Suppress 'Can't chdir to' warnings for File::Find
by choroba (Cardinal) on Apr 28, 2016 at 16:25 UTC
    The documentation mentions the following:
    no warnings 'File::Find';

    Have you tried it? It works for me.

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

      Well, humble pie, here I come. I saw that and assumed it was unrelated...tried it and it works perfectly. Thanks!

        In case there are warnings that aren't related to permission issues that show up, instead of disabling warnings, you could stash any warnings File::Find throws into an array, and quickly grep through them for lines not matching any expected warnings to ensure nothing bad is happening in the background without being notified:

        use warnings; use strict; use File::Find; my @warnings; { local $SIG{__WARN__} = sub {push @warnings, shift;}; find ({wanted => \&wanted}, '.'); } warn "this warning outside of File::Find, so will print normally\n"; sub wanted { # do stuff } print "caught: $_\n" for @warnings; __END__ this warning outside of File::Find, so will print normally caught: Can't cd to (./) test: Permission denied at find.pl line 10.
Re: Suppress 'Can't chdir to' warnings for File::Find
by stevieb (Canon) on Apr 28, 2016 at 16:28 UTC

    In your wanted() sub (near the top), it should work as you expect if you add a return if -d $File::Find::name && ! -x $File::Find::name;.

    That checks to see if the current item is a directory, and checks whether the effective UID can traverse into it.

      Thanks for the alternative suggestion. I used the no warnings approach, but thought I would try yours as well. My logic was that maybe it would speed up processing, but surprisingly, it just about doubled the time from 6 secs to 11secs.

      That was totally unexpected! If I weren't knee deep in deadlines, I would explore why that is...speed is definitely of the essence for this function.

        My gut on the performance hit is stats the item in question twice. I could be COMPLETELY wrong on that though.
Re: Suppress 'Can't chdir to' warnings for File::Find
by ikegami (Patriarch) on Apr 29, 2016 at 17:05 UTC
    That's what the no_chdir option is all about!

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (3)
As of 2024-04-20 01:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found