简体   繁体   English

Perl:使用GetOptions进行命令行处理

[英]Perl: command-line processing with GetOptions

Problem: I've got a script that can be called in one of the following ways: 问题:我有一个可以通过以下方式之一调用的脚本:

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

Meaning, the -w flag is optional, but either -i or -d or -r or -t must be specified. 这意味着-w标志是可选的,但必须指定-i-d-r-t

If the user doesn't call the script in any of those ways, the function usage should be called. 如果用户未通过任何上述方式调用脚本,则应调用函数usage

My attempt: 我的尝试:

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;

Doesn't make much sense to have 5 variables to represent one choice. 有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);
}

Basically, use all of the various options and test the combinations you want. 基本上,使用所有各种选项并测试所需的组合。

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
#

However, I would recommend you going long , that is with parameter names. 但是,我建议您使用参数名进行long操作 By default, Getopt::Long will allow for parameter abriviations. 默认情况下, Getopt::Long将允许参数缩写。 If -i is for integer , ( I don't know, you didn't give too many clues to what these parameters mean), go ahead and specify -integer as a parameter (and use $integer instead of $opt_i ). 如果-iinteger ,(我不知道,您对这些参数的含义没有提供太多线索),请继续指定-integer作为参数(并使用$integer代替$opt_i )。 Users can abbreviate -integer as -i since no other parameter starts with -i . 用户可以将-integer缩写为-i因为没有其他参数以-i开头。 You could also use aliases too: 您也可以使用别名

 "divider|i" => \$divider,

Then, a user could use -divider or -i as the parameter. 然后,用户可以使用-divider-i作为参数。

Now to this Pod::Usage... 现在到这个Pod ::用法...

Perl has a documentation system called POD (it stands for Plain Old Documentation ). Perl有一个称为POD的文档系统(它代表Plain Old Documentation )。 It's rather simple to pick up, and it allows you to add documentation right into your program. 拿起它相当简单,它允许您直接在程序中添加文档。

=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

You can see this documentation by using the perldoc command which comes with Perl: 您可以使用Perl随附的perldoc命令查看此文档:

$ perldoc script.pl

This will print out your POD in full glory. 这将全面打印您的POD。 If anyone needs to know how to use your program and what it does, it's right there. 如果有人需要知道如何使用您的程序以及它的功能,就在那里。

Pod::Usage will by default print out the Synopsis section of your POD and then exit. 默认情况下, Pod::Usage将打印出POD的“ 概要”部分,然后退出。 It's great when a user put the wrong option, or types script.pl -help . 当用户输入错误的选项或键入script.pl -help时,这很棒。

There are many options. 有很多选择。 For example, you can print out the Synopsis and the Options section, or the entire POD, or selected bits and pieces. 例如,您可以打印“ 摘要”和“ 选项”部分,或整个POD,或选定的点点滴滴。

It is a great way to document your code, and should be encouraged by everyone. 这是记录您的代码的好方法,并且应该受到所有人的鼓励。

The only issue I had is that the documentation on the POD documentation doesn't specifically mention that command paragraphs (the lines that start with an equal sign) must have a blank line before and after them. 我唯一遇到的问题是POD文档上的文档没有特别提到命令段落 (以等号开头的行)前后必须有空白行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM