Как я могу разрешить неопределенные параметры при разборе аргументов с Getopt

Если у меня есть командная строка, как:

my_script.pl -foo -WHATEVER

Мой сценарий знает о --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

дает

Неизвестный вариант: что угодно
оставшиеся варианты:

3 ответа

Решение

Вам необходимо настроить параметр "pass_through" через Getopt::Long::Configure("pass_through");

Затем он поддерживает фактические параметры (например, материал, начинающийся с "-" и без специального разделителя "-" для обозначения конца "реальных" параметров).

Вот цитата из perldoc:

  • 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'
        ];

Разве оставшиеся (непарсированные) значения не остались в @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 - так что я бы рекомендовал конвертировать!

Я думаю, что ответ здесь, к сожалению, таков: "Нет, нет способа сделать это в точности так, как вы просите, используя Getopt::Long, без разбора @ARGV самостоятельно". Эфир имеет достойный обходной путь, хотя. Это особенность, поскольку большинство людей обеспокоены тем, что любой аргумент, подобный параметру, воспринимается как ошибка. Обычно вы можете сделать

GetOptions('foo' => \$foo) 
    or die "Whups, got options we don't recognize!";

захватить / предотвратить передачу нечетных опций, а затем вы можете исправить пользователя при использовании. Кроме того, вы можете просто пройти и игнорировать их.

Другие вопросы по тегам