Pergunta

Estou escrevendo um script que pode fazer algo como:

script-name --resource1= xxx --resource2= xxx

Mas isso pode ir até 50+.Existe uma maneira de fazer GetOpt aceitar nomes de opções dinâmicas?

Foi útil?

Solução

E quanto à geração automática da lista de opções para Getopt :: Long comoexemplo abaixo?Como a lista de opções provavelmente será bem longa, usar Getopt :: ArgvFile permitevocê deve fornecer o arquivo de configuração com opções em vez de especificá-las na linha de comando.

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;

Outras dicas

Sim, já que descobri como fazer isso sozinho, pois queria aceitar um argumento - # e Getopt :: Long não aceita regex como nome de opção. Então foi isso que eu fiz:

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
);

Em seguida, defini a função 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);
}

Então, o que é necessário é a opção pass_through, uma verificação do que você quer e definir essas coisas quando for visto. Acima eu tinha opções indefinidas passadas para minha função. Eu uso isso para verificações de arquivo e para uma opção especial - # onde # é algum número inteiro. Se não corresponder, adiciono a uma matriz de badargs, pois isso não fará com que GetOptions falhe, então tenho que verificar essa matriz após o retorno de GetOptions para ver se erros foram vistos. Você também pode fazer com que ele termine em erro de opção encerrando a função de retorno de chamada com die("!FINISH");, que fará com que GetOptions encerre o script.

O que eu uso isso é a capacidade de ter algo como -20 FILE1 -30 FILE2, portanto, as opções podem ser substituídas por arquivos subsequentes. Vejo que você consegue fazer algo semelhante com uma verificação da primeira parte do nome da opção e depois do valor. Portanto, se todas as suas opções começarem com --resource, procure por algo assim em sua função: /^--?(resource\w+)=(.*)$/ e adicione à matriz de opção.

De qualquer forma, espero que isso ajude.

Outro método para tentar seria apenas usar algum tipo de arquivo de configuração.Parece que esse pode ser o método mais fácil de escrever e analisar, visto que você planeja ter uma grande quantidade de informações.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top