in reply to Recursive opendir without

Try this:
use strict; my $dir = "/"; my $file; sub openNewDir { my $dir = shift; my $dh; opendir ($dh, $dir); while ($file = readdir ($dh)) { next if (($file eq '.') || ($file eq '..')); if (-d "$dir/$file") { openNewDir("$dir/$file"); } else { # Do something with the file } } close ($dh); } openNewDir ($dir);
These are the important changes:
  1. Open to an anonymous typeglob ($dh) instead of a handle (DIR).
  2. Test -d on "$dir/$file" instead of "$file".
  3. Keep $dir in lexical scope by "my"ing it at the beginning of the subroutine.
  4. Concatonate the directory and file correctly for the recursive call.
  5. UPDATE: Skip the '.' and '..' directories.
Hope this helps...

-Ton

-----

Be bloody, bold, and resolute; laugh to scorn
The power of man...

Replies are listed 'Best First'.
Re: Re: Recursive opendir without
by bobione (Pilgrim) on Apr 11, 2001 at 18:29 UTC
    That is exactly what I wanted. I need to declare a my $dh.
    But I steel don't understand why my opendir ($dir, $dir) doesn't work :(
    Thank you very much.
    BoBiOne

      I assume that you mean "why my opendir($dh,$dir) doesn't work". That is because when you opendir($dh,"/") and then readdir($dh), you'll get a file name like "usr" and then try to do opendir($dh,"usr") which isn't the same as opendir($dh,"/usr"). If your current working directory happens to be "/", then that call will work (by luck) and you'll read a file name like "home" and try opendir($dh,"home") when you should be doing opendir($dh,"/usr/home").

      So you either need to chdir into each directory before you open the next one (and then chdir back out when you are done) or you need to keep track of the full path to each directory as you go so you can prepend it in several places.

              - tye (but my friends call me "Tye")
        No, it's not a problem of "/" (even if my first exemple could be wrong).
        I mean : if I take ton's code and replace $dh by $dir :
        use strict; # ---> IMPORTANT my $dir = "toto"; my $file; sub openNewDir { my $dir = shift; ### my $dh; opendir ($dir, $dir); # ---> MODIFICATION while ($file = readdir ($dir)) { # ---> MODIFICATION here too next if (($file eq '.') || ($file eq '..')); if (-d "$dir/$file") { openNewDir("$dir/$file"); } else { # Do something with the file print "($file)\n"; } } close ($dir); # ---> MODIFICATION here too } openNewDir ($dir);
        (I comment important lines).
        use strict warm me : Can't use string ("toto") as a symbol ref while "strict refs" in use at test.pl line 13. (that mean during the readdir()).
        And when I was trying to explain you, I think I understood why ;) (but not sure)
        It could be that readdir() don't know if $dir is a "Directory Handler" or the "Directory" itself...

        BoBiOne
      Alternatively, have a look at Re: How can I create an array of filenames?. That's truly recursive, and simple.

      Jeroen
      "We are not alone"(FZ)

      With a little change:

      our @list; findfile('*'); sub findfile{ my $glob = shift; for ( glob $glob ){ push( @list, $_) if -f; findfile( $_.'/*' ) if -d; } }