Как разрешить параметры undefined при анализе аргументов с помощью Getopt
Если у меня есть командная строка вроде:
my_script.pl -foo -WHATEVER
My script знает о --foo
, и я хочу, чтобы Getopt устанавливал переменную $opt_foo
, но я ничего не знаю о -WHATEVER
. Как я могу сказать Getopt проанализировать параметры, о которых я рассказал, а затем получить остальные аргументы в строковой переменной или списке?
Пример:
use strict;
use warnings;
use Getopt::Long;
my $foo;
GetOptions('foo' => \$foo);
print 'remaining options: ', @ARGV;
Затем, выписывая
perl getopttest.pl -foo -WHATEVER
дает
Unknown option: whatever
remaining options:
Ответы
Ответ 1
Вам нужно настроить опцию "pass_through" с помощью Getopt::Long::Configure("pass_through");
Затем он поддерживает фактические параметры (например, материал, начинающийся с "-", и без специального разделителя "-", чтобы обозначить конец "реальных" опций).
Здесь perldoc quote:
-
pass_through (по умолчанию: отключено)
Параметры, которые неизвестны, неоднозначны или снабжены недопустимым значением параметра, передаются в @ARGV
вместо того, чтобы помечены как ошибки. Это позволяет писать сценарии оболочки, которые обрабатывают только часть аргументов командной строки, предоставленных пользователем, и передают оставшиеся опции в какую-либо другую программу.
Здесь пример
$ cat my_script.pl
#!/usr/local/bin/perl5.8 -w
use Getopt::Long;
Getopt::Long::Configure("pass_through");
use Data::Dumper;
my %args;
GetOptions(\%args, "foo") or die "GetOption returned 0\n";
print Data::Dumper->Dump([\@ARGV],["ARGV"]);
$ ./my_script.pl -foo -WHATEVER
$ARGV = [
'-WHATEVER'
];
Ответ 2
Не оставшиеся (нераскрытые) значения просто остались в @ARGV
? Если ваш дополнительный контент начинается с тире, вам нужно указать конец списка опций с помощью --
:
#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long;
use Data::Dumper;
my $foo;
my $result = GetOptions ("foo" => \$foo);
print Dumper([ $foo, \@ARGV ]);
Затем вызов:
my_script.pl --foo -- --WHATEVER
дает:
$VAR1 = [
1,
[
'--WHATEVER'
]
];
PS. В MooseX::Getopt "оставшиеся" параметры из командной строки помещаются в атрибут extra_argv
как arrayref, поэтому я ' d рекомендуем конвертировать!
Ответ 3
Я думаю, что ответ здесь, к сожалению, "нет, нет способа сделать это точно так же, как вы просите, используя Getopt:: Long, без разбора @ARGV самостоятельно". Тем не менее, у Ether есть достойное решение. Это особенность, поскольку большинство людей обеспокоено тем, что любой аргумент, подобный аргументу, воспринимается как ошибка. Обычно вы можете делать
GetOptions('foo' => \$foo)
or die "Whups, got options we don't recognize!";
для захвата/предотвращения передачи нечетных параметров, а затем вы можете исправить пользователя при использовании. Кроме того, вы можете просто пройти и проигнорировать их.