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

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

I am hoping I can gain an insight to a problem I am having. I am new to Perl and I am trying to write a code snippet that will allow me to list the directory contents of a directory that is specified taking user input. What I am intending to do is take the user input, place it in a variable and then pass that variable along to chdir and such but it will not change the directory. If I hardcode the directory into the variable ($dir = /etc) then it works fine. This is what I have so far in terms of code... can someone please show me what would work?

<code>
#!/usr/bin/perl

use strict;
use warnings;

print "Enter name of directory (fully qualified path): ";
my $dir = <STDIN>;
chdir($dir)
@files = <$dir/*>;
foreach $file (@files)
{
print $file "\n";
}
<code>

Replies are listed 'Best First'.
Re: STDIN help for a new Perl coder
by ikegami (Patriarch) on Jul 15, 2009 at 16:51 UTC
    You forgot to remove the trailing newline
    chomp( my $dir = <STDIN> );
      Thank you I was not aware of the trailing new line following it... I will read up on chomp.
Re: STDIN help for a new Perl coder
by gwadej (Chaplain) on Jul 15, 2009 at 16:54 UTC

    Look at chomp. That should give you a clue.

    When you have a question about the value of a variable. It's a good idea to print it with delimiters around the value. Not all characters are visible.

    print "[$dir]\n";
    G. Wade

      Thank you, I will look at the delimiters as well to try that out.

Re: STDIN help for a new Perl coder
by kennethk (Abbot) on Jul 15, 2009 at 17:03 UTC
    I see a couple of issues.
    1. You neglected to remove the trailing newline from your input. You can take care of this by chomping the value:

      chomp(my $dir = <STDIN>);

    2. You omitted a semicolon on line 8:

      chdir($dir);

    3. You neglected to declare your variables @files and $file on lines 9 and 10:

      my @files = <$dir/*>; foreach my $file (@files)
    4. You omitted a comma (Comma Operator) from your print statement. Without it, Perl will read that as printing "\n" to the lexical file handle in $file.

      print $file, "\n";

    You also might want to read Markup in the Monastery since you haven't followed site protocol. Rather than using a glob, I'd also use opendir, readdir and closedir to protect yourself from typos and pathological file names.

    #!/usr/bin/perl use strict; use warnings; print "Enter name of directory (fully qualified path): "; chomp(my $dir = <STDIN>); opendir my($dirhandle), $dir or die "No such directory: $dir"; my @files = readdir($dirhandle); closedir($dirhandle); foreach my $file (@files) { print $file, "\n"; }

      Thank you Kennethk, I will look over the Monestary Markup guidelines... I missed that when I originally posted and was not aware of them since this is my first visit.

      I will definitely take your advice. Some of what you mentioned I should no better than to miss, mainly the ; and the declaring of variables but neglected somehow.

      If you happen to know of any good resources for Perl besides Learning Perl the Hard Way or Picking up Perl I would be interested in finding some.

Re: STDIN help for a new Perl coder
by linuxer (Curate) on Jul 15, 2009 at 16:59 UTC

    Welcome here and to Perl.

    If you read User input like that, you must know, that the linebreak will also be stored in your variable. So you must remove it; see chomp for details.

    chomp( my $dir = <STDIN> );

    Each statement should be completed with a ';', your chdir misses one.

    You should check if chdir was successful and do something if it wasn't ($! contains the system's error message).

    chdir( $dir ) or die "$dir: $!\n";

    If you already changed into $dir, you must not specify it again in the glob pattern.

    As you are using strict, you need to declare each new variable. You did it right with $dir, but not with @files.

      Thank you for the advice... I forgot about declaring the @files but will do so. I also was not aware of the linebreak being stored... I did not know Perl did this. I will look into the chomp command.

      I will also add the system error message to the chdir line to give the message like you suggest.