user623990
user623990

Reputation:

What's the correct way to handle command line arguments in Perl script?

I'm trying to create a script/application which accepts command line arguments when run. Of course, this is a day-to-day thing, but seeing as this is the first time I'm doing it, I'm looking for some guidance. Let's say my script can take these kinds of command line arguments:

script -a -p /path/to/pipe -l mail.Error -m [email protected]
script -a -l mail.Error -m [email protected] -p /path/to/pipe

and so on....

Due to the flexible nature of command line scripts, the arguments you can pass to it can some in a variety of orders and could be missing/have invalid arguments. Now, I know this can be solved by being very strict about how the arguments must show up (first -a, then -p with a path, then -l with a log facility/priority and finally -m with a valid email) and by testing all possible occurrences of them.

But there has to be a better way. This is incredibly inefficient (to me) and I was wondering if there was a better way of doing things. I want to remain as flexible as possible and just make things work instead of focusing on strict usage.

Upvotes: 2

Views: 620

Answers (3)

toolic
toolic

Reputation: 62236

Getopt::Long can automatically parse your command line into a hash variable. The order on the command line does not matter. You can check if options are given or not by checking hash keys.

use warnings;
use strict;
use Getopt::Long;

my %opts;
GetOptions(\%opts, qw(a p=s l=s m=s)) or die;

Upvotes: 0

gpojd
gpojd

Reputation: 23085

I use Getopt::Long for arguments.

Untested example:

use Getopt::Long;
## set defaults
my $path   = '/tmp';
my $log = 'm.Error';
my $email = '[email protected]';
my $a = 0;
my $result = GetOptions ("path=s"  => \$path,
                         "log=s"   => \$log,
                         "a"       => \$a,
                         "email=s" => \$email);
## both script -a -p /path/to/pipe -l mail.Error -m [email protected]
## and script -a -l mail.Error -m [email protected] -p /path/to/pipe
## should work now

Upvotes: 6

Keith Thompson
Keith Thompson

Reputation: 263647

Use Getopt::Std if you only want 1-character options, Getopt::Long if you want to support longer argument names.

Upvotes: 2

Related Questions