Domanda

Sto scrivendo uno script che può fare qualcosa del tipo:

nome-script --resource1= xxx --resource2= xxx

Ma questo può arrivare a 50+.C'è un modo per fare in modo che GetOpt accetti i nomi delle opzioni dinamiche?

È stato utile?

Soluzione

Che dire della generazione automatica dell'elenco di opzioni per Getopt :: Long comeesempio sotto?Poiché l'elenco delle opzioni sarà probabilmente piuttosto lungo, l'utilizzo di Getopt :: ArgvFile consentedi fornire al file di configurazione le opzioni invece di specificarle sulla riga di 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;

Altri suggerimenti

Funzionerebbe con lo stesso nome dell'opzione ripetuto ?

Ad esempio: script-name --resource=xxx --resource=xxx

Sì, poiché ho appena capito come farlo da solo perché volevo accettare un argomento - # e Getopt :: Long non accetta regex per il nome di un'opzione. Quindi questo è quello che ho fatto:

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

Ho quindi definito la funzione 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);
}

Quindi ciò che serve è l'opzione pass_through, un controllo di ciò che desideri e l'impostazione di quelle cose quando vengono visualizzate. Sopra ho avuto opzioni indefinite passate alla mia funzione. Lo uso per il controllo dei file e per un'opzione speciale - # dove # è un numero intero. Se non corrisponde, aggiungo a un array badargs, poiché ciò non causerà il fallimento di GetOptions, quindi devo controllare questo array dopo il ritorno da GetOptions per vedere se sono stati rilevati errori. Puoi anche farla terminare in caso di errore di opzione terminando la funzione di callback con die("!FINISH"); che farà sì che GetOptions termini lo script.

Quello per cui lo uso è la possibilità di avere qualcosa come -20 FILE1 -30 FILE2, quindi le opzioni possono essere sovrascritte per i file successivi. Vedo che sei in grado di fare qualcosa di simile con un controllo per la prima parte del nome dell'opzione e poi il valore. Quindi, se tutte le tue opzioni iniziano con --resource, cerca qualcosa di simile nella tua funzione: /^--?(resource\w+)=(.*)$/ e poi aggiungi nell'array di opzioni.

Comunque, spero che questo aiuti.

Un altro metodo da provare sarebbe usare semplicemente una sorta di file di configurazione.Sembra che questo potrebbe essere il metodo più semplice sia per scrivere che per analizzare, dato che prevedi di avere una grande quantità di informazioni.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top