Getopt :: Long pode acomodar nomes de opções de variáveis?
-
27-10-2019 - |
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?
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
Funcionaria com o mesmo nome de opção repetido ?
Por exemplo: script-name --resource=xxx --resource=xxx
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.