Как я могу разрешить неопределенные параметры при анализе args с помощью 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

дает

Unknown option: whatever
remaining options:

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!";

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