Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

question n File::Find

by skyworld_chen (Acolyte)
on Oct 30, 2012 at 09:43 UTC ( #1001477=perlquestion: print w/replies, xml ) Need Help??
skyworld_chen has asked for the wisdom of the Perl Monks concerning the following question:


I wrote a piece of code named as "cy_find" like this:

use File::Find; .... .... find (\&wanted, "$target_path"); sub wanted { open temp_file_cy, "$File::Find::name; print "hello 1\n" if (-r tep_file_cy); close temp_file_cy; }

it is strange for some files the linux returns :

"-r on closed filehandle temp_file_cy at ../cy_find line 87"

can anybody tell me why I was operating on "closedfilehandle"? thanks

Replies are listed 'Best First'.
Re: quston n File::Find
by 2teez (Vicar) on Oct 30, 2012 at 09:54 UTC

    Here are some of the things I spotted in your wanted sub. open temp_file_cy, "$File::Find::name;

    1. I think you want to use a lexical variable my $temp_file_cy instead of a bareword temp_file_cy as your file-handle
    2. then, "$File::Find::name has only one quote at the beginning.
    3. If you may, use 3 agrument open function, then check error if file is not opened
    4. I will advise you use warnings and strict in your script. As it shows several 'mis-typed' variables. It will help alot
    With a second check on the usage of the file test using "-r" in this line:
    print "hello 1\n" if (-r tep_file_cy);
    check perldoc -f -r
    -r File is readable by effective uid/gid.
    If 'tep_file_cy' is the file you trying to check up, not been used as file-handle.
    Except, you have something else in mind.

    If you tell me, I'll forget.
    If you show me, I'll remember.
    if you involve me, I'll understand.
    --- Author unknown to me

      thanks for your kind reply.

      a) in fact I insert"use warnings" and "use strict" in my code. I just omitted them for simple demo of my code. And in my real code I didn't miss quote, it is a type error here. Any way, thanks for your kind remind.

      b) accroding to your ideas,I use

      open $temp_file_cy, "$File::Find::name"

      it is interesting that I haven't see "open $filehandle ...", but always "open filehandle ...". in the text book. Can you tell me the difference between them? thanks.

      c) I have checked the attributes of those files, they are all -rw-rw----, so I guess "-r " should be ok here. In fact what I want to do really is this:

       my @matching = grep {/$pattern/} <temp_file_cy>;  

      I always get this message: " readline() on unopened filehandle temp_file_cy at ../cy_find line 99", which make me to insert code "-r temp_file_cy" to see what happened

      can you give me some help on this? thanks

        Maybe there was an error in opening the file. Try autodie or check for errors like this:
        unless (open my $filehandle,"<",$File::Find::name) { warn $!; return; }
        Sorry if my advice was wrong.
Re: question on File::Find (cd)
by tye (Sage) on Oct 30, 2012 at 13:40 UTC

    Why do you open the file just to close it again? You know -r can take a file name, not just a file handle, right?

    Putting variables in quotes when you don't need to may bite you in future when you get to using references. But maybe you won't put variables containing references in quotes and so it is just a style issue.

    But the main problem with your code is that $File::Find::name will often not be useful for opening a file (nor for checking the permissions on a file).

    If you call File::Find's find() and pass it "foo" as the directory to search, then find() will chdir into the "foo" directory (by default) before doing much of any work. If you have a file "foo/bar", then your 'wanted' subroutine will be called with $_ set to "bar" and $File::Find::name set to "foo/bar".

    Since your program is now cd'd into "foo", trying to open "foo/bar" would only work if you also had a "foo/foo/bar" file. So try:

    sub wanted { print "hello 1\n" if -r $_; }

    - tye        

      thank you for your reply. I tried your code and it WORKS! thank you very much and thanks for every one who had replied my questions.

      by the way, I would like to do some operation to the file, I tried some code like this:

      print "hello 1\n" if (-r $_); my @matching = grep {/$my_pattern/} <$_>;

      I failed with this code. I have to

      open $filehandle,"<", $_" or die .... my @matching = grep {/$my_pattern/} <$_>;

      did I do something wrong? or is there any better way to do grep or similar operateion in the $_? thanks.

        Use File::Slurp to read a file in one command.
        Sorry if my advice was wrong.
Re: question n File::Find
by zentara (Archbishop) on Oct 30, 2012 at 11:02 UTC
    Yeah, my comment on it, is that it looks like when he copied the file contained in $File::Find::name, it copied it's permissions too, and they were readonly. So then he tried to open it for writing and gets the error. Or else the directory where the script tried to create the file didn't have write perms, in this case, the right to create a file. Write in the directory context means create a new file. Read only means you can't create a file there. Just a guess. :-)

    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh

      thanks for your reply. I have checked the attributes and they are -rw-rw----. Thanks.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1001477]
Approved by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (8)
As of 2018-06-21 02:58 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (117 votes). Check out past polls.