Command line argument handling is done through the built-in array @ARGV, which contains all parameters passed to the script at runtime (excluding the script name itself). This is the basic way for any CLI Perl applications but has many nuances related to data types, encoding, parameter splitting, and pitfalls of automatic file reading.
From its early versions, Perl's @ARGV array has served as a standard "entry point" for startup arguments, similar to argv[] in C. However, Perl, being a general-purpose language and catering to text-related tasks, has added numerous additional tricks — for example, the <> expression, which is "linked" to the contents of @ARGV, allowing immediate reading from files listed as arguments.
Trivial reading of @ARGV is suitable only for simple cases. In complex CLI programs, there arises the task of handling options (like --help, -o file). Here, simple indexed reading becomes unsafe and inconvenient. It gets even more complicated with handling arguments that contain spaces, non-standard characters, or different encodings. Plus, there are issues with automatic file opening via the operator <> and unexpected behavior if elements of @ARGV are equal to, for example, "-" (stdin).
Reading simple arguments:
foreach my $arg (@ARGV) { print "Arg: $arg "; }
Typically, for options, a special module Getopt::Long is used:
use Getopt::Long; my $help; GetOptions('help' => \$help);
To read all files from @ARGV, the file contents can be read directly in a loop:
while (<>) { print; }
What happens if one of the command line arguments only contains a dash (-)?
In this case, when using the operator <>, Perl interprets '-' as standard input (stdin), not a filename.
perl script.pl - file.txt # Reading first from stdin, then from file.txt
Is it safe to modify @ARGV within the script?
Yes, this is standard practice for removing already processed arguments. Typically, after processing options, @ARGV is left with only "bare" file names or unrecognized parameters.
Do we need to do encode/decode when working with UTF-8 arguments in @ARGV?
It depends on the locale and environment. By default, Perl does not transform the encodings of @ARGV but accepts them "as is". Therefore, if filenames (or parameters) contain non-ASCII characters, it's advisable to explicitly decode strings using Encode if further processing in Perl is required.
A log parsing utility takes a list of files. The user accidentally specifies '-':
perl parse.pl - access.log
as a result — suddenly the program freezes and waits for input from the keyboard.
Pros:
Cons:
A CLI program reads arguments through Getopt::Long, explicitly handles all dash options, leaving in @ARGV only file names:
perl report.pl --input access.log --output report.txt
Pros:
Cons: