【问题标题】:Perl: command-line processing with GetOptionsPerl:使用 GetOptions 进行命令行处理
【发布时间】:2013-10-12 19:00:15
【问题描述】:

问题: 我有一个可以通过以下方式之一调用的脚本:

./script.pl -a
./script.pl [-w] -<i|d|r|t>

意思是,-w 标志是可选的,但必须指定 -i-d-r-t

如果用户不以上述任何方式调用脚本,则应调用函数usage

我的尝试:

sub fInv
{
    print "fInv"."\n";
}

sub fDisp
{
    print "fDisp"."\n";
}

sub fRanking
{
    print "fRanking"."\n";
}

sub fTickets
{
    print "fTickets"."\n";
}

sub usage
{
    print "Usage shown here.\n";
}

%options = (i => \&fInv, d => \&fDisp, r => \&fRanking, t => \&fTickets);

$write = 0;

GetOptions("a" => \&usage)
    or GetOptions("w" => \$write,
                    keys($options) => \&options) # This is clearly wrong
    or die usage;

【问题讨论】:

    标签: perl command-line-arguments


    【解决方案1】:

    用 5 个变量代表一个选择没有多大意义。

    my $type;
    my $opt_w;
    
    my $set_type = sub {
       my ($new_type) = @_;
       die "-$type and -$new_type cannot be used together\n"
          if defined $type && $new_type ne $type;
       $type = $new_type;
    };
    
    GetOptions(
       'help|h|?' => \&help,
       ( map { $_ => $set_type } qw( a i d r t ) ),
       'w' => \$opt_w,
    )
       or usage();
    
    usage("One of -a, -i, -d, -r or -t must be specified\n")
       if !defined($type);
    
    usage("-w cannot be used with -a\n")
       if $opt_w && $type eq 'a';
    

    sub help {
        print "...detailed help...\n";
        exit(0);
    }
    
    sub usage {
        print(STDERR $_[0]) if @_;
        print(STDERR "usage: script -a\n");
        print(STDERR "       script [-w] {-i|-d|-r|-t}\n");
        print(STDERR "Use script --help for more information\n");
        exit(1);
    }
    

    【讨论】:

      【解决方案2】:

      基本上,使用所有各种选项并测试您想要的组合。

      use strict;
      use warnings;
      use Getopt::Long;
      use Pod::Usage;      # Learn something new!
      
      
      my ( $opt_a, $opt_i, $opt_w, $opt_d, $opt_r, $opt_t, $opt_w );
      GetOoptions {
      
           a    => \$opt_a,
           i    => \$opt_i,
           w    => \$opt_w,
           d    => \$opt_d,
           r    => \$opt_r,
           t    => \$opt_t,
           help => \$help,
      } or die pod2usage ( -message => "You did it wrong" );
      
      if ( $help ) {
          pod2usage;
      }
      
      if ( $opt_a and ( $opt_w or $opt_d or $opt_r or $opt_t ) ) {
          pod2usage ( -message => "Either use '-a' by itself, or the other parameters" );
      }
      
      if ( not ( $opt_w and $opt_w and $opt_d and $opt_r and $opt_t ) {
      pod2usage ( -message => "You need to use parameters -d, -i, -r, or -t")
      
      #
      # And now to your regularly scheduled program
      #
      

      但是,我建议您使用 long,即使用参数名称。默认情况下,Getopt::Long 将允许参数缩写。如果-i代表整数,(我不知道,你没有给出太多线索来解释这些参数的含义),继续指定-integer作为参数(并使用$integer 而不是 $opt_i)。用户可以将-integer 缩写为-i,因为没有其他参数以-i 开头。你也可以使用别名

       "divider|i" => \$divider,
      

      然后,用户可以使用-divider-i 作为参数。

      现在到这个 Pod::Usage...

      Perl 有一个称为POD 的文档系统(它代表Plain Old Documentation)。它很容易上手,它允许您将文档直接添加到您的程序中。

      =pod
      
      =head1 NAME
      
      script.pl
      
      =head1 SYNOPSIS
      
          ./script.pl -a
      
      or
      
          ./script.pl [-w] -<i|d|r|t>
      
      =head1 DESCRIPTION
      
      blah, blah, blah, yadda, yadda, yadda
      
      =head1 OPTIONS
      

      您可以使用 Perl 附带的perldoc 命令查看此文档:

      $ perldoc script.pl
      

      这将完整地打印出您的 POD。如果有人想知道如何使用您的程序以及它的作用,它就在那里。

      Pod::Usage 默认会打印出您的 POD 的 Synopsis 部分,然后退出。当用户输入错误选项或输入script.pl -help 时,这非常棒。

      有很多选择。例如,您可以打印出 SynopsisOptions 部分,或整个 POD,或选定的部分。

      这是记录代码的好方法,应该受到所有人的鼓励。

      我遇到的唯一问题是POD documentation 上的文档没有特别提到命令段落(以等号开头的行)前后必须有一个空行他们。

      【讨论】:

        猜你喜欢
        • 2011-09-27
        • 1970-01-01
        • 2012-04-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-08
        • 2011-05-05
        相关资源
        最近更新 更多