【问题标题】:Parsing command line mutual exclusion flags with their specific options in perl with Getopt::Long使用 Getopt::Long 在 perl 中解析命令行互斥标志及其特定选项
【发布时间】:2020-07-08 12:19:50
【问题描述】:

我有几个相互排斥的标志,女巫有自己的选择。可以说,如果我调用“stop_service”标志,我想要一个“name”选项;但如果我调用“send_report”标志,我想要一个“电子邮件”选项。对于解析,我使用“Getopt::Long”。这是代码:

use Getopt::Long;

# Option vars
my $stop_service;   # flag
my $send_report;    # flag
my $name;           # string
my $email;          # string

# Get all possible options
GetOptions(
    # Flag and options for stop_service
    "stop_service"  => \$stop_service,      # Mutual Exclusion Flag
    "name=s"        => \$name,              # option string

    # Flag and options for send_report
    "send_report"   => \$send_report,       # Mutual Exclusion Flag
    "email=s"       => \$email,             # option string
);

# Parsing correct combinations
# --stop_service --name XXX
if (($stop_service and !$send_report)       # mutual exclusion
    and ($name && !$email))                 # options
{
    print "stop_service + name: \n";
    print $stop_service, " - ", $name, "\n";
}
# --send_report --email XXX
elsif ((!$stop_service and $send_report)    # mutual exclusion
    and (!$name && $email))                 # options
{
    print "send_report + email: \n";
    print $send_report, " - ", $email, "\n";
}
# HELP
else {
print <<DOC;
    Help in line 1.
    Help in line 2.
DOC
}

效果很好:

[getopt]$ perl 06_getopt_cond_3.pl --stop_service --name jumersindo
stop_service + name: 
1 - jumersindo
[getopt]$ perl 06_getopt_cond_3.pl --send_report --email jumer@jum.er
send_report + email: 
1 - jumer@jum.er
[getopt]$ perl 06_getopt_cond_3.pl --send_report --name
Option name requires an argument
    Help in line 1.
    Help in line 2.

是否有更“自动”的配置方式?或者我需要用“if”语句指定所有选项组合?

【问题讨论】:

    标签: perl args getopt-long


    【解决方案1】:

    基于Avoiding mix of certain arguments to script,我设法实现了这个解决方案。这个想法是只接受明确指定的选项并拒绝其他组合,例如:

    use strict;
    use Getopt::Long;
    
    # Option vars
    my %options= ();    
    
    # Get all possible options
    GetOptions(
        # Mutually exclusive flags
        "detener_servicio|stop_service"         => \$options{stop_service},
        "arrancar_servicio|start_service"       => \$options{start_service},
        "reiniciar_servicio|restart_service"    => \$options{restart_service},
        "registrar_servicio|record_service"     => \$options{record_service},
        "enviar_informe|send_report"            => \$options{send_report},
    
        # Options
        "nombre|name=s"                         => \$options{name},
        "script=s"                              => \$options{script}, 
        "ruta|path=s"                           => \$options{path}, 
        "ejecutables|execs=s"                   => \$options{execs},
        "email=s"                               => \$options{email},
    );
    
    if (only_specified_options(\%options, 'stop_service', 'name')) {
        print "Stoping service: ", $options{name}, "\n";
    }
    elsif (only_specified_options(\%options, 'start_service', 'name')) {
        print "Starting service: ", $options{name}, "\n";
    }
    elsif (only_specified_options(\%options, 'restart_service', 'name')) {
        print "Restarting service: ", $options{name}, "\n";
    }
    elsif (only_specified_options(\%options, 'record_service', 'name', 
                                             'script','path','execs')) {
        print "Recording service: ", $options{name},    " ", 
                                     $options{script},  " ", 
                                     $options{path},    " ", 
                                     $options{execs} ,  " ", "\n";
    }
    elsif (only_specified_options(\%options, 'send_report', 'email')) {
        print "Sending report: ", $options{email}, "\n";
    }
    else {
        print <<DOC;
    Usage:
        script --stop_service    --name <NAME>
        script --start_service   --name <NAME>
        script --restart_service --name <NAME>
        script --record_service  --name <NAME> --script <SCRIPT> 
                                 --path <PATH> --execs <EXECS>
        script --send_report     --email <EMAIL>
    DOC
    }
    
    # only_specified_options(\%options, 'option_1', 'option_2',..., 'option_n')
    # If only specified options are present => return true
    #   otherwise => false
    sub only_specified_options {
        my $opt_ref = shift;
        my %must_params = map { $_ => 1 } @_;
        my $result_bool = 1;
        
        while ((my $key, my $value) = each (%$opt_ref)) {
            $result_bool &&= (exists($must_params{$key})?$value:!$value);
        }
        return $result_bool;
    }
    

    【讨论】:

      猜你喜欢
      • 2010-10-27
      • 1970-01-01
      • 2013-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多