http://www.perlmonks.org?node_id=1029139

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

Hi All - Sincere apologies if this has been asked before and I am repeating. Just needed a quick input from experts here. May I know what I am doing wrong in below code. For some reason, the directories are not being processed recursively. I do see that the program finds a directory and the function is being called recursively. But, only one time it is being called and not working as expected.
#!/usr/bin/perl my $parent_dir = "/panther/home/efxprod/support"; process_dir($parent_dir); sub process_dir { my $dir = shift; print "Processing $dir\n"; opendir(SCR , $dir) or die "Can't open $dir: $!"; while( defined ($file = readdir SCR) ) { next if ($file =~ /\.$/ ); next if ($file =~ /\.txt$/ ); if ( $file =~ /\.sh$/ ) { print "not a regullar file: $file\n"; } elsif ( $file =~ /\.pl$/) { print "perl $file\n"; } elsif ( -d "$dir/$file" ) { print "directory : $file\n"; process_dir("$dir/$file/"); #next; #} elsif ( $file } else { print "Else :$file\n" if ( -B "$dir/$file"); } print "file -> $file\n"; } return; }

Replies are listed 'Best First'.
Re: Require input reading files recursively in perl
by CountOrlok (Friar) on Apr 17, 2013 at 13:22 UTC
    General disclaimer: use strict/warnings.

    Using a global filehandle (or in general any global variable that can be modified) with recursion is a *bad* idea. Instead use lexcials:
    opendir(my $SCR , $dir) or die "Can't open $dir: $!"; while( defined (my $file = readdir $SCR) )
    Don't forget to closedir when done.
      Thanks a lot. Below is the newer version and it works fine. Appreciate the time and your valuable input.
      #!/usr/bin/perl use strict; use warnings; my $parent_dir = "/panther/home/efxprod/support"; process_dir($parent_dir); sub process_dir { my $dir = shift; print "Processing $dir\n"; opendir(my $SCR , $dir) or die "Can't open $dir: $!"; while( defined (my $file = readdir $SCR) ) { next if ($file =~ /\.$/ ); next if ($file =~ /\.txt$/ ); if ( $file =~ /\.sh$/ ) { print "not a regullar file: $file\n"; } elsif ( $file =~ /\.pl$/) { print "perl $file\n"; } elsif ( -d "$dir/$file" ) { print "directory : $dir/$file\n"; process_dir("$dir/$file/"); #next; #} elsif ( $file } else { print "Else :$file\n" if ( -B "$dir/$file"); } print "file -> $file\n"; } closedir($SCR); }
Re: Require input reading files recursively in perl
by kcott (Archbishop) on Apr 17, 2013 at 13:19 UTC

    G'day jesuashok,

    How about you add these lines to your code and let Perl tell you what's wrong:

    use strict; use warnings;

    strict should tell you about $file in while( defined ($file = readdir SCR) ) which, I believe, is your immediate problem.

    warnings may pick up something I haven't spotted.

    Please endeavour to add these two lines to all your scripts.

    -- Ken

      This standard chunk of cargo-cult programming won't actually fix the OP's problem, since the global SCR directory handle will still get overwritten. A dose of "local" or "my" will fix it, and an explanation of what is happening would lead to the right solution.
      Just another Perler interested in Algol Programming.
Re: Require input reading files recursively in perl
by hdb (Monsignor) on Apr 17, 2013 at 13:12 UTC

    If you do _not_ want to do the recursion yourself, you also could use File::Find .

    UPDATE: added "not"

Re: Require input reading files recursively in perl
by choroba (Cardinal) on Apr 17, 2013 at 13:09 UTC
    readdir returns file names, not paths. To really access the file (as in opendir), you have to prepend the path to the file name.

    Update: My comment is irrelevant to the problem. I was not able read the code properly because it was placed in the signature part of the post which renders without syntax highlighting and other bells and whistles I am accustomed to.

    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ


      As you can see from above code, when I call the function recursively, I am passing arguments by doing pre-pend the directory name so that the opendir would know what the directory it should open. Did I get that wrong? Feel free to correct.