Options with Getopt::Long

Contents
Parsing options
Option types
Positional arguments
--help with Pod::Usage

Parsing options

@ARGV holds everything the shell passed after the script name, but splitting it by hand gets old after the second flag. Getopt::Long ships with Perl and does the job properly.

#!/usr/bin/perl use strict; use warnings; use Getopt::Long; my %opt = (verbose => 0, output => "-"); GetOptions( \%opt, "verbose|v+", "output|o=s", ) or die "usage: backup.pl [--verbose] [--output FILE]\n"; print "verbose: $opt{verbose}\n"; print "output: $opt{output}\n";

Each string describes one option: the name, optional aliases after a pipe, and a type suffix. The results land in the hash you passed by reference, so --verbose sets $opt{verbose}.

./backup.pl --verbose --output=log.txt

verbose: 1 output: log.txt

GetOptions returns false on a bad option and prints a warning of its own. Check the return value, otherwise a typo like --verbse silently does nothing.

Option types

The suffix after the option name decides what the user may write and what you receive. Four characters cover almost every command line tool:

GetOptions( \%opt, "verbose|v+", # counter: -v -v "force!", # boolean, --force / --noforce "output|o=s", # required string "tag=s@", # repeatable string "workers|j=i", # integer );

A bare name is a flag. The plus sign makes a counter, so -vvv gives three when bundling is enabled. The exclamation mark adds a negated form, and the at sign collects repeated values into an array reference.

Options accept both --output log.txt and --output=log.txt. Single letters also work with one dash: -o log.txt. To allow -vv as a bundle of single letters, configure it explicitly:

Getopt::Long::Configure("bundling");

Call Configure before GetOptions, once per program. Other useful settings are no_ignore_case to keep -v and -V distinct, and auto_abbrev to accept unique prefixes like --verb.

Positional arguments

Whatever is not an option stays in @ARGV, which is how you take file names after the flags. By default parsing stops at the first non-option word, so the rest is yours untouched:

my @files = @ARGV; die "no input files\n" unless @files; for my $file (@files) { print "processing $file\n"; }

./backup.pl -v src/ lib/

processing src/ processing lib/

If you want flags to be recognised after file names too — backup.pl src/ --verbose — enable permutation. Use GetOptionsFromArray(\@args, \%opt, ...) when the words do not come from @ARGV, for example in a wrapper script that forwards arguments.

--help with Pod::Usage

A tool without --help is a tool nobody else can use. The clean way is to write the help text as POD at the bottom of the script and let Pod::Usage print it:

use Pod::Usage; GetOptions( \%opt, "help|h" => sub { pod2usage(-exitval => 0, -verbose => 1) }, "verbose|v+", "output|o=s", ) or pod2usage(-exitval => 2); __END__ =head1 NAME backup.pl - copy a folder into an archive =head1 SYNOPSIS backup.pl [--verbose] [--output FILE] DIR...

-verbose => 2 prints the full manual page instead of the synopsis. Setting -exitval => 2 on a parse failure is the convention that tells a calling script the arguments were wrong, as opposed to the work failing later.

./backup.pl --help

Usage: backup.pl [--verbose] [--output FILE] DIR...

Write the synopsis once and let it serve both the help screen and the manual page. Users read it, and so will you in six months.

Next: Environment and %ENV

Article author: Arthur Isaev

Related articles
Perl
Perl course: zero to hero in 50 lessons
What is Perl and where it runs
Install Perl and check the version
Your first Perl script
The debugger as a REPL
Scalars and sigils
Numbers
Strings
Interpolation and quoting
Arrays
push, pop, shift and splice
Hashes
keys, values, exists and delete
Scalar and list context
Conditions and comparison
while, for, next and last
foreach and the default variable
Subroutines
Arguments in @_
References
Nested data structures
Regular expressions: match and anchors
Captures and named groups
Substitution with s///
split and join
grep and map
Sort and the Schwartzian transform
Read and write files
File tests and metadata
Directories and paths
die, warn and eval
Modules and Exporter
CPAN and cpanm
Objects with bless
Modern objects with Moo
Testing with Test::More
strict, warnings and diagnostics
Options with Getopt::Long
Environment and %ENV
system, backticks and pipes
One-liners with -n and -p
CSV and TSV processing
JSON with JSON::PP
HTTP clients with HTTP::Tiny
Sockets and IO::Socket
Databases with DBI
Capstone: todo CLI
Capstone: log report
Performance and profiling
Modern Perl tour
Hero roadmap: the whole course on one page
Install Perl on Windows 11
Install Perl on Ubuntu
Install Perl on Rocky Linux
Install Perl on macOS
Install Perl on FreeBSD
Perl in Docker

Search this site

Channel @aofeed Chat @aofeedchat

Contacts and cooperation:
I recommend our hosting beget.com
Write to info@aredel.com if you:
1. Want to write an article for our site or translate an article into your native language.
2. Want to place thematically relevant ads on the site.
3. Ads on my site pass maximum censorship. If you see an ad block unsuitable for school-age children, shocking or misleading - please contact us by e-mail
4. Found a mistake, inaccuracy, bug, etc. on the site. ... .......
5. Articles can be shared on social media by clicking a network icon: