Pregunta

Estoy escribiendo un guión que puede hacer algo como:

nombre de secuencia de comandos --resource1= xxx --resource2= xxx

Pero esto puede llegar hasta 50+.¿Hay alguna forma de hacer que GetOpt acepte nombres de opciones dinámicas?

¿Fue útil?

Solución

¿Qué pasa con la generación automática de la lista de opciones para Getopt :: Long comoejemplo a continuación?Dado que la lista de opciones probablemente sea bastante larga, el uso de Getopt :: ArgvFile permitedebe proporcionar el archivo de configuración con opciones en lugar de especificarlas en la línea de comandos.

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;

Otros consejos

Sí, ya que acabo de descubrir cómo hacerlo yo mismo, ya que quería aceptar un argumento - # y Getopt :: Long no acepta expresiones regulares como nombre de opción. Así que esto es lo que hice:

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

Luego definí la función 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);
}

Entonces, lo que se necesita es la opción pass_through, una verificación de lo que desea y configurar esas cosas cuando se ve. Arriba tenía opciones indefinidas pasadas a mi función. Lo uso para verificaciones de archivos y para una opción especial: # donde # es un número entero. Si no coincide, lo agrego a una matriz de badargs, ya que hacer esto no provocará que GetOptions falle, por lo que tengo que verificar esta matriz después de la devolución de GetOptions para ver si se observaron errores. También puede hacer que finalice en caso de error de opción al finalizar la función de devolución de llamada con die("!FINISH"); que hará que GetOptions termine el script.

Para lo que lo uso es la capacidad de tener algo como -20 FILE1 -30 FILE2, por lo que las opciones se pueden anular para los archivos posteriores. Veo que puede hacer algo similar con una verificación de la primera parte del nombre de la opción y luego el valor. Entonces, si todas sus opciones comienzan con --resource, busque algo como esto en su función: /^--?(resource\w+)=(.*)$/ y luego agréguelo a la matriz de opciones.

De todos modos, espero que esto ayude.

Otro método para probar sería simplemente usar algún tipo de archivo de configuración.Parece que este podría ser el método más fácil de escribir y analizar, dado que planea tener una gran cantidad de información.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top