Perl GetOpt::Long 带有可选参数的多个参数

Perl GetOpt::Long multiple arguments with optional parameter

这是我在 Whosebug 上的拳头 post。 :)

我正在尝试用 GetOpt::Long 解决这个问题。

./myscript -m /abc -m /bcd -t nfs -m /ecd -t nfs ...

-m为挂载点,-t为文件系统类型(可放,但不强制)。

  Getopt::Long::Configure("bundling");
  GetOptions('m:s@' => $mount, 'mountpoint:s@' => $mount,
             't:s@' => $fstype, 'fstype:s@'  => $fstype)

这不对,我无法配对正确的挂载和 fstype

./check_mount.pl -m /abc -m /bcd -t nfs -m /ecd -t nfs
$VAR1 = [
          '/abc',
          '/bcd',
          '/ecd'
        ];
$VAR1 = [
          'nfs',
          'nfs'
        ];

我需要填写未指定的文件类型,例如具有 "undef" 值。 对我来说最好的解决方案是获取哈希,例如...

%opts;
$opts{'abc'} => 'undef'
$opts{'bcd'} => 'nfs'
$opts{'ecd'} => 'nfs'

可能吗?谢谢。

来自 docs 的“参数回调”部分:

When applied to the following command line:
    arg1 --width=72 arg2 --width=60 arg3

This will call process("arg1") while $width is 80 , process("arg2") while $width is 72 , and process("arg3") while $width is 60.

编辑:按要求添加 MWE。

use strict;
use warnings;
use Getopt::Long qw(GetOptions :config permute);

my %mount_points;
my $filesystem;

sub process_filesystem_type($) {
    push @{$mount_points{$filesystem}}, $_[0];
}

GetOptions('t=s' => $filesystem, '<>' => \&process_filesystem_type);

for my $fs (sort keys %mount_points) {
    print "$fs : ", join(',', @{$mount_points{$fs}}), "\n";
}

./test -t nfs /abc /bcd -t ext4 /foo -t ntfs /bar /baz

ext4 : /foo

nfs : /abc,/bcd

ntfs : /bar,/baz

请注意,输入按文件系统类型排序,然后是挂载点。这与 OP 的解决方案相反。

直接用 Getopt::Long 做起来并不容易,但如果你可以稍微改变参数结构,比如

./script.pl --disk /abc --disk /mno=nfs -d /xyz=nfs

...以下将带您到达您想去的地方(请注意,缺少的类型将显示为空字符串,而不是 undef):

use warnings;
use strict;

use Data::Dumper;
use Getopt::Long;

my %disks;

GetOptions(
    'd|disk:s' => \%disks, # this allows both -d and --disk to work
);

print Dumper \%disks;

输出:

$VAR1 = {
          '/abc' => '',
          '/mno' => 'nfs',
          '/xyz' => 'nfs'
        };