2016-07-12 17 views
3

Dies ist meine erste Post auf Stackoverflow. :)Perl GetOpt :: Lange Mehrfachargumente mit optionalem Parameter

Ich versuche dieses Szenario mit GetOpt :: Long zu lösen.

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

-m Einhängepunkt und -t Typ von Dateisystem (angeordnet werden kann, aber es ist nicht obligatorisch).

Getopt::Long::Configure("bundling"); 
    GetOptions('m:[email protected]' => \$mount, 'mountpoint:[email protected]' => \$mount, 
      't:[email protected]' => \$fstype, 'fstype:[email protected]' => \$fstype) 

Das ist nicht richtig, ich bin nicht in der Lage Paar richtige Halterung und fstype

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

Ich fülle brauchen nicht näher bezeichnet -fstype z.B. mit "undef" -Wert. die beste Lösung für mich Hash würde bekommen wie ...

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

Ist es möglich? Vielen Dank.

+0

Sie versuchen, eine sehr spezifische Reihenfolge für Optionen zu erzwingen, aber ich denke nicht, dass das sehr häufig oder intuitiv ist. Wenn ich ein Benutzer Ihrer Anwendung wäre, würde ich erwarten, dass "-m foo -t bar" dasselbe ist wie "-t bar -m foo". Du könntest das vielleicht mit Getopt :: Long machen, aber ich denke, ein anderes Design wäre besser. – ThisSuitIsBlackNot

Antwort

1

Dies wird nicht leicht sein, mit Getopt::Long direkt zu tun, aber wenn Sie die Argumentstruktur etwas ändern können, wie zum Beispiel zu

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

... Nachfolgend erhalten Sie erhalten, wo Sie wollen sein (beachten Sie, dass ein fehlender Typ als leere Zeichenfolge erscheint, nicht 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; 

Ausgang:

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

[Sie müssen es nicht einmal selbst aufteilen.] (Http: //perldoc.perl.org/Getopt/Long.html # Options-with-hash-values) Vorsicht vor Mount-Punkten, die '=' enthalten. – ThisSuitIsBlackNot

+0

Guter Anruf @ThisSuitIsBlackNot ... Ich habe irgendwie diesen Teil der Dokumentation in meinen Jahren verpasst :) Das ist praktisch! (Antwort aktualisiert) – stevieb

0

Aus dem "Argument Rückruf" des 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: In MWE wie gewünscht.

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

Hinweis, dass die Eingänge als Typ-Dateisystem dann Einhängepunkte geordnet. Dies ist umgekehrt zu der Lösung des OP.

+1

es würde wahrscheinlich enorm helfen, wenn Sie ein funktionierendes Beispiel basierend auf der OPs Frage ... – stevieb

+0

@stevieb Ich fügte die MWE, wie gewünscht. Wahrscheinlich hätte ich das früher machen sollen, aber ich fühlte mich faul. – Tim

+0

Vielen Dank für die Lösung! –