Подтвердить что ты не робот

Как разрешить параметры 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:
4b9b3361

Ответ 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!";

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