Как я могу передать опции Getopt :: Long подпрограмме, которая также является опцией? - PullRequest
2 голосов
/ 13 декабря 2011

Я пытаюсь настроить Getopt :: Long для обработки аргументов из скрипта конфигурации.

Вот мой стартер;

#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long;

my $config_file = '';

GetOptions (

    'config|c=s' => \$config_file,
    'add|a' => \&add_server,
    'del|d' => \&del_server,

);

sub add_server {

print "$config_file\n";

}

sub del_server {

# Left blank for now.

}

Странно, что я сталкиваюсь спроблема, когда я запускаю свой скрипт с чем-то вроде этого,

./config.pl -a -c config.xml

Он НЕ печатает опцию -c, но если я запускаю его так,

./config.pl -c config.xml -a

все работает так, как должно.

Мне кажется, я понимаю причину, почему это связано с правильным исполнением заказа?

Вопрос в том, как можноЯ чиню это?Должен ли я использовать Getopt :: Long в сочетании с @ARGV?

В конечном итоге я пытаюсь передать аргументы командной строки в вызываемую мной подпрограмму.Поэтому, если -a or --add, я хочу, чтобы опции -c or --config передавались в подпрограмму при ее вызове.

Есть идеи?

Ответы [ 5 ]

3 голосов
/ 13 декабря 2011

Я не вижу необходимости вызывать подпрограмму напрямую из вызова GetOptions. Управляйте заказом так:

use strict;
use warnings;
use Getopt::Long;

my %opts = (config => '');

GetOptions(\%opts, qw(
   config|c=s
   add|a
   del|d
));

add_server() if $opts{add};
del_server() if $opts{del};

sub add_server {    
    print "$opts{config}\n";
}

sub del_server {}
0 голосов
/ 02 июля 2014
GetOptions(
        'arg=s' => sub { print "$_[1]\n"; },
);
0 голосов
/ 13 декабря 2011

Обратные вызовы вызываются при обнаружении опций, поэтому add_server вызывается до того, как -c встречается, когда вы делаете

./config.pl -a -c config.xml

На основании последней информации вы теперь хотите:

use Getopt::Long qw( GetOptions );

GetOptions(
   'a=s' => \my $opt_a,
   'd=s' => \my $opt_d,
   'h=s' => \my $opt_h,
   'p=s' => \my $opt_p,
) or usage();
0 голосов
/ 13 декабря 2011

Немного сварив пример ...

use strict;
use warnings;
use Getopt::Long;

my $config_file = '';

GetOptions (

    'config|c=s' => \$config_file,
    'add|a' => sub{add_server($config_file);}
);

sub add_server
{

    my $config=shift;

    if(defined($config))
    {
        print "Got this for a config file: $config\n";
    }
    else
    {
        print "No argument supplied to add_server\n";
    }

}

... и выполнение config.pl -c blurg -a возвращает вывод Got this for a config file: blurg, а выполнение config.pl -a -c blurg возвращает Got this for a config file:.

Итак, я подозреваю, что происходит то, что параметры назначаются в указанном порядке. Таким образом, в первом случае $config_file присваивается аргументу -c, а затем вызывается подпрограмма add_server (с правильным аргументом), тогда как во втором случае add_server немедленно запускается без аргумента, а затем $config_file назначено.

Помимо всего этого, я бы рекомендовал сделать -a логическим значением и делать все, что вы хотите, если он включен (и если указан аргумент для -c).

0 голосов
/ 13 декабря 2011

Включите параметр pass_through в Getopt :: Long, чтобы он игнорировал неизвестные параметры, затем один раз вызовите GetOptions для ваших параметров, снова отключите его, а затем снова используйте GetOptions для вашей команды.

...