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

my script takes in command line arguments
eg. myscript.pl -5 /home/slok

the script works fine if I don't supply the path argument
but give an error message when I supply a path...

message as follows:
========
invalid top directory at /usr/lib/per5/5.6.0/File/Find.pm line 279
===========

my code is as follows
===========

use File::Find; use strict; my $path = "."; #default path my $num = 10; #default number my $num_flag = 0; my @paths; #array to hold paths my $num_pahts = 0; foreach my $argv (@ARGV) { if ( $argv =~ m/^-/ ) { $num_flag++; if ($num_flag > 1) { print STDERR "Cannot have more than one entry for number o +f users\n"; usage_exit(1); } $num = substr($argv, 1); print ("num is, $num\n"); } # if it matches slash or is a path if ( $argv =~ m/^\// ) { $num_paths++; print ("num_path, $num_paths\n"); $paths[$num_paths] = $argv; } } # set default path if no path argument is supplied if ($num_paths == 0) { @paths = <$path/*>; } my %size; my @sorted; find (sub { $size{$File::Find::name} = -s if -f || -l; }, @paths );

Replies are listed 'Best First'.
Re: File::Find complain about invalid top directory?
by rchiav (Deacon) on Apr 22, 2001 at 03:34 UTC
    Two things I see here.

    1) you mispelled my $num_pahts = 0.

    2) you're incrementing your count before you're adding an element to the array. Your array starts with 0, and $paths[0] is empty and when it tries to shift the element off of there and there's nothing there, it tells you that there's an invalid dirctory. I'd also suggest looking into push to fill your array.

    Hope this helps..
    Rich

    Addition: While I'm at it, I'll give you some other pointers.

    1) Instead of counting the elements in @ARGV, you could just do this:

    push @paths, <$path/*> unless @ARGV;

    2)If you really wanted to find out how many elements there were (which you really don't need here), you could just put @ARGV in scalar context. But remember, the top element is one less than that because arrays start with 0.

      I tried your suggestion, but still face the same error message..

      ===============

      use File::Find; use strict; my $path = "."; # default path my $num = 10; # -n default number of users my $num_flag = 0; my @paths ; # array to hold paths my $num_paths = 0; my @subpaths ; my $size = 0; foreach my $argv (@ARGV) { # if it matches dash if ( $argv =~ m/^-/ ) { $num_flag++; if ($num_flag > 1) { print STDERR "Cannot have more than one entry for number o +f users\n"; usage_exit(1); } $num = substr($argv, 1); print ("num is, $num\n"); } # if it matches slash or is a path if ( $argv =~ m/^\// ) { push @paths, <$argv/*> unless @ARGV; print ("argv, $argv\n"); print ("num_path, $num_paths\n"); $num_paths++; } } # set default path if no path argument is supplied if ($num_paths == 0) { @paths = <$path/*>; print ("assigning default path\n"); } my $i=0; foreach $i (@paths) { print ("atpaths, \n"); } my %size; my @sorted; find (sub { $size{$File::Find::name} = -s if -f || -l; }, @paths );
        I think I must have confused you here. your line:
        push @paths, <$argv/*> unless @ARGV;
        isn't doing what you want it to do. Change that line to just  push @paths, $argv; There's no reason to do any globbing there. Read up on push to see what it's doing.

        what you should do to assign the default path if none is specified is <code> push @paths, "." unless @paths; <code> That should replace your section where you check to see if the count == 0. This code will push "." onto @paths if there's nothing in @paths.

        Hope this helps..
        Rich