SYNOPSIS use Getopt::Long::Subcommand; # exports GetOptions my %opts; my $res = GetOptions( summary => 'Summary about your program ...', # common options recognized by all subcommands options => { 'help|h|?' => { summary => 'Display help message', handler => sub { my ($cb, $val, $res) = @_; if ($res->{subcommand}) { say "Help message for $res->{subcommand} ..."; } else { say "General help message ..."; } exit 0; }, 'version|v' => { summary => 'Display program version', handler => sub { say "Program version $main::VERSION"; exit 0; }, 'verbose' => { handler => \$opts{verbose}, }, }, # list your subcommands here subcommands => { subcmd1 => { summary => 'The first subcommand', # subcommand-specific options options => { 'foo=i' => { handler => \$opts{foo}, }, }, }, subcmd1 => { summary => 'The second subcommand', options => { 'bar=s' => \$opts{bar}, 'baz' => \$opts{baz}, }, }, }, # tell how to complete option value and arguments. see # Getopt::Long::Complete for more details, the arguments are the same # except there is an additional 'subcommand' that gives the subcommand # name. completion => sub { my %args = @_; ... }, ); die "GetOptions failed!\n" unless $res->{success}; say "Running subcommand $res->{subcommand} ..."; To run your script: % script Missing subcommand % script --help General help message ... % script subcmd1 Running subcommand subcmd1 ... % script subcmd1 --help Help message for subcmd1 ... % script --verbose subcmd2 --baz --bar val Running subcommand subcmd2 ... % script subcmd3 Unknown subcommand 'subcmd3' GetOptions failed! DESCRIPTION STATUS: EARLY RELEASE, EXPERIMENTAL. This module extends Getopt::Long with subcommands and tab completion ability. How parsing works: First we call Getopt::Long::GetOptions with the top-level options, passing through unknown options if we have subcommands. Then, subcommand name is taken from the first argument. If subcommand has options, the process is repeated. So Getopt::Long::GetOptions is called once at every level. Completion: Scripts using this module can complete themselves. Just put your script somewhere in your PATH and run something like this in your bash shell: complete -C script-name script-name. See also shcompgen to manage completion scripts for multiple applications easily. How completion works: Environment variable COMP_LINE or COMMAND_LINE (for tcsh) is first checked. If it exists, we are in completion mode and @ARGV is parsed/formed from it. We then perform parsing to get subcommand names. Finally we hand it off to Complete::Getopt::Long. FUNCTIONS GetOptions(%cmdspec) => hash Exported by default. Process options and/or subcommand names specified in %cmdspec, and remove them from @ARGV (thus modifying it). Will warn to STDERR on errors. Actual command-line options parsing will be done using Getopt::Long. Return hash structure, with these keys: success (bool, false if parsing options failed e.g. unknown option/subcommand, illegal option value, etc), subcommand (array of str, subcommand name, if there is any; nested subcommands will be listed in order, e.g. ["sub1", "subsub1"]). Arguments: * summary => str Used by autohelp (not yet implemented). * options => hash A hash of option names and its specification. The specification is the same as what you would feed to Getopt::Long's GetOptions. * subcommands => hash A hash of subcommand name and its specification. The specification looks like GetOptions argument, with keys like summary, options, subcommands (for nested subcommands). Differences with Getopt::Long's GetOptions: * Accept a command/subcommand specification (%cmdspec) instead of just options specification (%ospec) like in Getopt::Long). * This module's function returns hash instead of bool. * Coderefs in options will receive an extra argument $res which is the result hash (being built). So the arguments that the coderefs get is: ($callback, $value, $res) FAQ How to avoid modifying @ARGV? How to process from another array, like Getopt::Long's GetOptionsFromArray? Instead of adding another function, you can use local. { local @ARGV = ['--some', 'value']; GetOptions(...); } # the original @ARGV is restored SEE ALSO Getopt::Long Getopt::Long::Complete Perinci::CmdLine - a more full featured command-line application framework, also with subcommands and completion. Pod::Weaver::Section::Completion::GetoptLongSubcommand