perl 如何将Getopt::Long选项传递给也是选项的子例程?

s4n0splo  于 2023-08-06  发布在  Perl
关注(0)|答案(5)|浏览(148)

我正在尝试设置Getopt::Long来处理配置脚本中的参数。
以下是我的starter:

#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long;

my $config_file = '';

GetOptions (    
    'config|c=s' => \$config_file,
    'add|a' => \&add_server,
    'del|d' => \&del_server,        
);

sub add_server {    
    print "$config_file\n";    
}

sub del_server {    
    # Left blank for now.    
}

字符串
奇怪的是,当我运行我的脚本时,我遇到了一个问题:
./config.pl -a -c config.xml
它不打印-c选项,但如果我这样运行它,
./config.pl -c config.xml -a
它就像它应该的那样工作。
我想我明白了为什么;这跟订单的执行有关系吧?
我该怎么解决?我应该将Getopt::Long@ARGV结合使用吗?
最后,我试图将命令行参数传递到我调用的子例程中。因此,如果-a--add,我希望-c--config的选项在调用子例程时传递到子例程中。
有什么想法吗

wbgh16ku

wbgh16ku1#

我不认为有必要直接从GetOptions调用调用子例程。像这样控制顺序:

use strict;
use warnings;
use Getopt::Long;

my %opts = (config => '');

GetOptions(\%opts, qw(
   config|c=s
   add|a
   del|d
));

add_server() if $opts{add};
del_server() if $opts{del};

sub add_server {    
    print "$opts{config}\n";
}

sub del_server {}

字符串

klsxnrf1

klsxnrf12#

把这个例子稍微简化一下...

use strict;
use warnings;
use Getopt::Long;

my $config_file = '';

GetOptions (

    'config|c=s' => \$config_file,
    'add|a' => sub{add_server($config_file);}
);

sub add_server
{

    my $config=shift;

    if(defined($config))
    {
        print "Got this for a config file: $config\n";
    }
    else
    {
        print "No argument supplied to add_server\n";
    }

}

字符串
运行config.pl -c blurg -a返回输出Got this for a config file: blurg,运行config.pl -a -c blurg返回Got this for a config file:
所以,我怀疑正在发生的是,选项是按照给出的顺序分配的。因此,在第一种情况下,$config_file被分配给-c参数,然后调用add_server子例程(使用正确的参数),而在第二种情况下,add_server立即被无参数地触发,然后分配$config_file
除此之外,我建议将-a设置为布尔值,如果启用了它(并且提供了-c的参数),则可以执行任何您想执行的操作。

wgxvkvu9

wgxvkvu93#

回调在遇到选项时被调用,因此在遇到-c之前调用add_server

./config.pl -a -c config.xml

字符串
根据最新信息,您现在需要:

use Getopt::Long qw( GetOptions );

GetOptions(
   'a=s' => \my $opt_a,
   'd=s' => \my $opt_d,
   'h=s' => \my $opt_h,
   'p=s' => \my $opt_p,
) or usage();

kxe2p93d

kxe2p93d4#

在Getopt::Long上启用pass_through选项,以便它将忽略未知选项,然后为您的选项调用GetOptions一次,再次禁用它,然后再次为您的命令使用GetOptions。

jxct1oxe

jxct1oxe5#

GetOptions(
        'arg=s' => sub { print "$_[1]\n"; },
);

字符串

相关问题