How do you use shell I/O redirection to pass in arguments into Perl scripts?

Viewed 76

Sorry if this is a really fundamental question to ask as I am quite new to Perl.

How would you add implement arguments into a Perl script using the I/O redirection symbols (> and <)?

e.g.

./program.pl file.txt

This would work with using $ARGV[0], $ARGV[1] etc in the Perl script, but instead I want to use arguments passed in like this:

./program.pl < file.txt
2 Answers

The shell doesn't pass either < or file.txt to Perl when you run ./program.pl < file.txt. The content of the file can be read from standard input. It's quite probable that you'd use:

while (<>)
{
    …
}

to process the input in the Perl script. It will read each file name specified, or standard input if no names are specified. There are tricks to detect when the file changes if you need them.

That doesn't pass either < or file.txt to Perl. That tells the shell to redirect perl's standard input.

To read from standard input, you use STDIN.

while (<STDIN>) {
   chomp;
   print "Got: $_\n";
}

However, that is very rarely done. Most of the time, you want to read from the special handle ARGV instead.

When you read from ARGV, all of the files named by the program's arguments (all those in @ARGV) are treated as one large file. If no argument were passed to the program (@ARGV is empty), reading from ARGV reads from STDIN instead. This gives you the flexibility found in all well-designed unix tools (cat, grep, etc, etc, etc).

Say you have this program (./a):

while (<>) {   # Same as <ARGV>
   chomp;
   say "Got: $_";
}
$ ./a file1.txt file2.txt
Got: Line 1 from file1.txt
Got: Line 2 from file1.txt
Got: Line 1 from file2.txt
Got: Line 2 from file2.txt

$ ./a <file1.txt
Got: Line 1 from file1.txt
Got: Line 2 from file1.txt

$ grep -h 'Line 1' file1.txt file2.txt | ./a
Got: Line 1 from file1.txt
Got: Line 1 from file2.txt

Only the last two would work if you used STDIN.

Related