Milan Čížek
Milan Čížek

Reputation: 77

Perl GetOpt::Long multiple arguments with optional parameter

this is my fist post on stackoverflow. :)

I'm trying to solve this scenario with GetOpt::Long.

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

-m is mount point and -t is type of file system (can be placed, but it is not mandatory).

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

This is not right, i'm not able pair proper mount and fstype

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

I need fill unspecified fstype e.g. with "undef" value. the best solution for me would be get hash such as...

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

Is it possible? Thank you.

Upvotes: 3

Views: 702

Answers (2)

Tim
Tim

Reputation: 1527

From the "Argument callback" section of the 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.

EDIT: Add MWE as requested.

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

Note that the inputs are ordered as filesystem type then mountpoints. This is reversed from the OP's solution.

Upvotes: 1

stevieb
stevieb

Reputation: 9296

This won't be easy to do with Getopt::Long directly, but if you can change the argument structure a bit, such as to

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

...the following will get you to where you want to be (note that a missing type will appear as the empty string, not 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;

Output:

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

Upvotes: 1

Related Questions