4

I'm doing a perl script and I need to get multiple values from the command line. Example:

perl script.pl --arg1 op1 op2 op3

I'm using Getopt::Long and I can get this to work:

perl script.pl --arg1 op1 --arg1 op2 --arg1 op3

But I really need (want) the first option.

I checked in their documentation and this is supposed to do what I want:

GetOptions('arg1=s{3}' => \@myArray);

http://search.cpan.org/~jv/Getopt-Long-2.38/lib/Getopt/Long.pm#Options_with_multiple_values

But I'm getting this error:

Error in option spec: "arg1=f{3}"

Any ideas / solutions?

Chris911
  • 4,131
  • 1
  • 23
  • 33
  • Do you need a separate utility for your script's arguments? All the arguments passed from the command line are stored within the $ARGV array. You can then sort and keep track of them internally within your script. source: http://www.cyberciti.biz/faq/howto-pass-perl-command-line-arguments/ Alternatively, you could include your one argument and the user must wrap them in quotes: perl script.pl --arg1 "op1 op2 op3" – OrionRogue May 11 '12 at 20:13
  • I thought about the quotes and might end up using this if I don't find another solution. I'm aware I could possibly use $ARGV but I have many arguments and Getopt::Long really helps keep track of everything and unfortunately it changes ARGV. – Chris911 May 11 '12 at 20:22
  • Just an idea: maybe there is something wrong with the shell. Can you do some simple print-debugging to be assured that you get what you expect in your script? – ArtMat May 11 '12 at 20:29
  • When I use the above code and I can't run anything as the script crashes before anything is done with the error I mentioned. – Chris911 May 11 '12 at 20:32

4 Answers4

4

Your code works for me, but it looks like that feature was only added to Getopt::Long recently (version 2.35), so you might have an old version of Getopt::Long. Run

perl -MGetopt::Long -le'print $Getopt::Long::VERSION;'

to see what version you have.

Robert Young
  • 313
  • 1
  • 5
  • Yea I already checked the version and I'm running 2.38. However I just realized clients might use an older version of perl or their servers so I might have to find another solution. Still find it strange it doesn't work here though. – Chris911 May 11 '12 at 20:23
  • 3
    That's weird. If it helps, I was running 2.35 on perl 5.8.8. If you want to keep using Getopt::Long but you want to mix in your own @ARGV processing, add `Getopt::Long::Configure('pass_through');` before running GetOptions. That way, anything that GetOptions doesn't recognize is left in @ARGV and you can process it yourself. – Robert Young May 11 '12 at 20:53
  • Thanks I'll take a look at pass_through. Perl v5.10.1 and Getopt::Long v2.38 here. – Chris911 May 11 '12 at 20:55
4

I think your problem could be f{3}. f is used for float arguments (real numbers). You should use the s specifier if you have strings as arguments. Regarding the number of arguments, the documentation says:

It is also possible to specify the minimal and maximal number of arguments an option takes. foo=s{2,4} indicates an option that takes at least two and at most 4 arguments. foo=s{,} indicates one or more values; foo:s{,} indicates zero or more option values.

Take into account hise note from docs and adjust to your needs.

ArtMat
  • 2,110
  • 12
  • 24
  • My bad about the f in the example I'm actually using s. I already read the doc and tried all the available options. – Chris911 May 11 '12 at 20:23
2

I'm not sure why folks didn't offer this solution, but this post is so old, it's probably too late now to be helpful.

There isn't an automatic way to do this that I've found.

What you need to do is quote the multiple arguments and parse them inside the code:

perl myscript.pl -m 'a b c'

and then split the -m argument value inside the code and do whatever is necessary from there.

Gangadhar
  • 10,248
  • 3
  • 31
  • 50
Kevin
  • 21
  • 1
0

Similar question to getoptions function perl multi value not working, I guess ... Anyways, it seems that just using "optlist=s" => \@list, works for me, to store duplicate / repeat options in an array; this is my version:

$ perl --version | grep This && perl -MGetopt::Long -le'print $Getopt::Long::VERSION;'
This is perl, v5.10.1 (*) built for i686-linux-gnu-thread-multi
2.38

An example (test.pl):

#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long;
my $numone = 0;
my $numtwo = 1;
my @list=();
my $result;
$result = GetOptions (
  "numone=i" => \$numone,
  "numtwo=i"   => \$numtwo,
  "optlist=s" => \@list,
);

printf("result: %d;\n", $result);
printf("numone: %d, numtwo %d, optlist:\n", $numone, $numtwo);

foreach my $tmplist (@list) {
  printf(" entry: '%s'\n", $tmplist);
}

Test output:

$ perl test.pl --numone 10 --numtwo 20 --optlist testing --optlist more --optlist options
result: 1;
numone: 10, numtwo 20, optlist:
 entry: 'testing'
 entry: 'more'
 entry: 'options'
Community
  • 1
  • 1
sdaau
  • 36,975
  • 46
  • 198
  • 278