Может ли Getopt :: Long содержать имена переменных? - PullRequest
1 голос
/ 13 июня 2011

Я пишу скрипт, который может сделать что-то вроде:

имя-сценария --resource1 = xxx --resource2 = xxx

Но это может доходить до 50+. Есть ли способ заставить GetOpt принимать динамические имена опций?

Ответы [ 4 ]

1 голос
/ 25 июля 2011

Да, поскольку я только что понял, как это сделать сам, так как я хотел принять аргумент - #, а Getopt :: Long не принимает регулярное выражение для имени опции.Вот что я сделал:

use Getopt::Long qw(:config pass_through);

my $ret=GetOptions(
    \%gops,
    'lines|l',  # lines/records to display
    ... cut ...
    '<>' => \&filearg,          # Handle file names also attach current options
);

Затем я определил функцию filearg ():

sub filearg {
    my $arg=shift;

    # First see if it is a number as in -20 as shortcut for -l 20
        if ($arg =~ /^--?(\d)+$/) {
        $gops{'lines'}=$1;
    } elsif (-f "$arg" && -r "$arg") {
        my %ops=%gops;
        $fops{$arg}=\%ops;
        push(@files, $arg);
    } else {
        push(@badargs, $arg);
    }
    return(undef);
}

Итак, что нужно, так это опция pass_through, проверка того, что вы хотите, иустановка этих вещей, когда видно.Выше у меня были неопределенные опции, переданные моей функции.Я использую это для проверки файлов и для специальной опции - # где # - некоторое целое число.Если он не совпадает, я добавляю в массив badargs, так как это не приведет к сбою GetOptions, поэтому я должен проверить этот массив после возврата из GetOptions, чтобы увидеть, были ли обнаружены ошибки.Вы также можете завершить его при ошибке опции, завершив функцию обратного вызова с помощью die("!FINISH");, что заставит GetOptions завершить сценарий.

Для чего я использую, это возможность иметь что-то вроде -20 FILE1 -30FILE2, поэтому параметры могут быть переопределены для последующих файлов.Я вижу, что вы можете сделать что-то подобное с проверкой первой части имени опции, а затем значения.Поэтому, если все ваши опции начинаются с --resource, найдите в своей функции нечто подобное: /^--?(resource\w+)=(.*)$/, а затем добавьте в массив опций.

В любом случае, надеюсь, это поможет.

1 голос
/ 13 июня 2011

Как насчет автоматической генерации списка опций для Getopt :: Long , как в примере ниже? Поскольку список параметров, скорее всего, будет довольно длинным, использование Getopt :: ArgvFile позволит вам указывать в файле конфигурации параметры, а не указывать их в командной строке.

use Getopt::Long;
use Getopt::ArgvFile;
use Data::Dump;

my @n = (1 .. 10);    # how many resources allowed
my %opts = (
    port                  => ':i',
    http_version          => ':s',
    invert_string         => ':s',
    ssl                   => '',
    expect                => ':s',
    string                => ':s',
    post_data             => ':s',
    max_age               => ':i',
    content_type          => ':s',
    regex                 => ':s',
    eregi                 => ':s',
    invert_regex          => '',
    authorization         => ':s',
    useragent             => ':s',
    pagesize              => ':s',
    expected_content_type => ':s',
    verify_xml            => '',
    rc                    => ':i',
    hostheader            => ':s',
    cookie                => ':s',
    encoding              => ':s',
    max_redirects         => ':i',
    onredirect_follow     => ':i',
    yca_cert              => ':s',
);

my %args = ();
GetOptions(\%args,
    map {
        my $i = $_;
        ( "resource$i:s", map { "resource${i}_$_$opts{$_}" } keys %opts )
    } @n
) or die;

dd \%args;
1 голос
/ 13 июня 2011

Будет ли работать с тем же именем опции повторяется ?

Например: script-name --resource=xxx --resource=xxx

0 голосов
/ 13 июня 2011

Еще один способ - просто использовать какой-нибудь файл конфигурации. Похоже, что это может быть самый простой способ для записи и анализа, учитывая, что вы планируете иметь большой объем информации.

...