3

Exact error:

$ ./script.pl file.txt  
Can't open file.txt: No such file or directory at ./script.pl line 17. 
Use of uninitialized value in chomp at ./script.pl line 17. 
Username: Password:

I'm writing a script that takes a filename from the commandline and then writes its output to it:

#!/usr/bin/perl
use warnings;
use strict;
use Term::ReadKey;

my @array;
my $user;
my $pass;

# get login info
print "Username: ";
chomp($user = <>); # line 17
print "Password: ";
ReadMode 2;
chomp($pass = <>);
ReadMode 0;
print " \n";

# ...
# connect to database, and save the info in "@array" 
# ...

# save the array to a file
if (defined($ARGV[0])) {
    open (MYFILE, ">".$ARGV[0]) or die "Can't open ".$ARGV[0].": $!\n";
    foreach (@array) {
        print MYFILE $_."\n";
    }
    close (MYFILE);
# otherwise, print the names to the screen
} else {
    foreach (@array) {
        print $_."\n";
    }
}

However if I replace ARGV[0] with "file.txt" or something similar, printing to the file works fine. If I do not provide a filename, the script works fine. My hunch is that the print statement is interfering with the iostream buffer but I can't figure out how to fix it.

Austin Moore
  • 1,414
  • 6
  • 20
  • 43
  • The lesson to learn here is to take user input of that sort [not by reading from STDIN, but as command-line options](http://stackoverflow.com/a/10957826). – daxim Jun 13 '12 at 14:23

2 Answers2

5

That is how the magic diamond operator works in Perl. If you start the script with an argument, it tries to read input from the file. If you feed it a standard input, it reads from there.

choroba
  • 231,213
  • 25
  • 204
  • 289
3

Use <STDIN>, not <>, to read from standard input if you are planning to use @ARGV.

Or, even better, read directly from terminal (if STDIN is a terminal). A quick search brought up Term::ReadKey, but I haven't tried it myself.

Dallaylaen
  • 5,268
  • 20
  • 34