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

Hi monks, im was trying to open a dir from perl and then get all its files with this code:
#!/usr/bin/perl -w use strict; my @files; opendir(DIR,"/some_dir"); while(<DIR>){ next if (/^.$/); @files = readdir(DIR,$_); }
but this code gave me an error, refering to a closed filehandle, that in this case is a dirhandle can somebody help me plz.

Replies are listed 'Best First'.
Re: Opendir error
by IlyaM (Parson) on Jan 17, 2003 at 13:35 UTC
    Likely opendir didn't open directory for some reason. Add error reporting to find why:
    opendir(DIR,"/some_dir") or die "Cannot open directory: $!";
    Update: Actually your usage of readdir and <> operator is incorrect. readdir accepts only one argument - directory handle and <> can read only from file handles. Correct code should look like:
    #!/usr/bin/perl -w use strict; opendir DIR, '/some_dir' or die "Cannot open directory: $!"; my @files = grep !/^.$/, readdir DIR; closedir DIR;

    --
    Ilya Martynov, ilya@iponweb.net
    CTO IPonWEB (UK) Ltd
    Quality Perl Programming and Unix Support UK managed @ offshore prices - http://www.iponweb.net
    Personal website - http://martynov.org

Re: Opendir error
by vek (Prior) on Jan 17, 2003 at 13:48 UTC
    As IlyaM points out, you should always check the return codes from functions. opendir will return 1 on success and 0 on failure. I would code it slightly differently:
    opendir(DIR, $some_dir) || die "Could not open $some_dir - $!\n"; for my $fileFound(readdir(DIR)) { my $fullPath = $some_dir . "/" . $fileFound; next if (-d $fullPath); # do stuff with each file in $some_dir }
    -- vek --
Re: Opendir error
by gjb (Vicar) on Jan 17, 2003 at 13:49 UTC

    I think you want something along the following lines:

    use strict; opendir(DIR,".") or die("Can't open directory '$!'"); while (my $file = readdir(DIR)) { next if $file =~ /^\.{1,2}$/; print "$file\n"; } closedir(DIR);
    A dir handle can only be read by readdir, not via the diamond <>. You probably want to exclude the . directory, so you have to escape the . in the regex and most probably you'd also prefer not to have .. either.

    Hope this helps, -gjb-

      Don't promote the /^\.{1,2}$/ meme. It doesn't work against malicious people who create files named ..\nfoo. For that you have to use \z instead of $, and by then it is starting to become quite unreadable.

      It is much better to write

      next if $file eq '.' or $file eq '..';

      Of course, a pendant might also go as far as saying

      next if $file eq File::Spec->curdir or $file eq File::Spec->updir;

      Personally I don't bother with that, but it does make for nice cross-platform code. See special directory entries for another thread on the question.


      print@_{sort keys %_},$/if%_=split//,'= & *a?b:e\f/h^h!j+n,o@o;r$s-t%t#u'
        Yes. And depending on the processing job, I would encourage the use of !/^\./ whenever possible. Filenames beginning with a dot are supposed to be "hidden", so unless you need to process "hidden" files as well, you should ignore all names that start with a dot.

        jdporter
        The 6th Rule of Perl Club is -- There is no Rule #6.