如何将Getopt :: Long选项传递给也是一个选项的子程序?

时间:2011-12-13 00:23:45

标签: perl config subroutine getopt-long

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

这是我的首发;

#!/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一起使用吗?

Ultimatly我试图让命令行args进入我正在调用的子程序。因此,如果-a or --add我希望-c or --config的选项在调用它时传递给子例程。

有什么想法吗?

5 个答案:

答案 0 :(得分:3)

我认为不需要直接从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 {}

答案 1 :(得分:0)

将示例简化一点......

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的参数)。

答案 2 :(得分:0)

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

./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();

答案 3 :(得分:0)

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

答案 4 :(得分:-1)

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