2010-06-08 14 views
17

Parsen Wenn ich eine Befehlszeile haben wie:Wie kann ich nicht definierte Optionen erlauben, wenn args mit Getopt

my_script.pl -foo -WHATEVER 

Mein Skript kennt --foo, und ich möchte Getopt Variable $opt_foo, setzen aber ich weiß nicht, irgendetwas über -WHATEVER. Wie kann ich Getopt anweisen, die Optionen, die ich ihm gesagt habe, auszuwerten und dann die restlichen Argumente in einer String-Variablen oder einer Liste abzurufen?

Ein Beispiel:

use strict; 
use warnings; 

use Getopt::Long; 

my $foo; 

GetOptions('foo' => \$foo); 

print 'remaining options: ', @ARGV; 

Dann Ausgabe

perl getopttest.pl -foo -WHATEVER

 
Unknown option: whatever 
remaining options: 

Antwort

20

Sie müssen „pass_through“ Option über Getopt::Long::Configure("pass_through");

konfigurieren Dann ist es tatsächlich Optionen (zB Material, beginnend mit „-“ und ohne die spezielle „-“ Trennzeichen zu bedeuten das Ende der „echten“ Optionen) unterstützen .

hier Perldoc Zitat:

  • pass_through (Standard: deaktiviert)

    Optionen, die mit einem ungültigen Optionswert unbekannt, zweideutig oder geliefert werden, sind in @ARGV durchlaufen statt wie gekennzeichnet werden Fehler. Dadurch können Wrapper-Skripts geschrieben werden, die nur einen Teil der vom Benutzer bereitgestellten Befehlszeilenargumente verarbeiten, und die verbleibenden Optionen an ein anderes Programm übergeben.

Hier ist ein Beispiel

$ cat my_script.pl 
#!/usr/local/bin/perl5.8 -w 

use Getopt::Long; 
Getopt::Long::Configure("pass_through"); 
use Data::Dumper; 
my %args; 
GetOptions(\%args, "foo") or die "GetOption returned 0\n"; 
print Data::Dumper->Dump([\@ARGV],["ARGV"]); 

$ ./my_script.pl -foo -WHATEVER   
$ARGV = [ 
      '-WHATEVER' 
     ]; 
+1

A ha, das würde erklären, warum ich es nicht gefunden habe ... :) – Ether

+4

Ich finde es absolut nervig zu lesen über einige nette Option auf perldoc Website und dann zurück zu meiner mesosischen Corporate Perl-Installation und finden Sie, dass die perfekte Option Ich habe festgestellt, erfordert einen Flusskondensator oder mindestens ein CPAN-Modul Upgrade – DVK

+1

Sind Sie sicher, 'pass_through' ist nicht verfügbar mit 5.8? Ich habe gerade "perldoc Getopt :: Long" für 5.6.1 überprüft (und Sie dachten, Sie wären prähistorisch;)) und es ist da. – Zaid

1

gibt, sind die verbleibenden (unparsed) Werte einfach hinter sich gelassen in @ARGV? Wenn Ihr zusätzliche Inhalte mit Bindestrichen beginnt, müssen Sie mit einem -- das Ende der Optionsliste anzuzeigen:

#!/usr/bin/perl 
use strict; 
use warnings; 
use Getopt::Long; 
use Data::Dumper; 

my $foo; 
my $result = GetOptions ("foo" => \$foo); 
print Dumper([ $foo, \@ARGV ]); 

Dann ruft:

my_script.pl --foo -- --WHATEVER 

gibt:

$VAR1 = [ 
      1, 
      [ 
      '--WHATEVER' 
      ] 
     ]; 

PS . In MooseX::Getopt, die "verbleibenden" Optionen von der Befehlszeile werden in das extra_argv Attribut als Arrayref - also ich würde empfehlen zu konvertieren!

+0

Sie sind nicht, wenn sie wie Optionen aussehen. Stattdessen wird ein Fehler wie "Unbekannte Option: WHATEVER" an STDERR ausgegeben. –

+0

@Robert: Ihr Kommentar und meine Bearbeitung im Äther gekreuzt :) – Ether

+0

:] In der Tat! Haha, ich habe der Frage ein solches Beispiel hinzugefügt. –

0

Ich denke, die Antwort hier ist leider "nein, es gibt keinen Weg, es genau so zu machen, wie du fragst, mit Getopt :: Long, ohne @ARGV selbst zu analysieren." Ether hat jedoch eine gute Lösung. Für die meisten Leute ist es ein Feature, dass jedes option-artige Argument als Fehler erfasst wird. Normalerweise können Sie tun,

GetOptions('foo' => \$foo) 
    or die "Whups, got options we don't recognize!"; 

zu erfassen/verhindern, dass ungerade Optionen übergeben werden, und dann können Sie den Benutzer auf Nutzung korrigieren. Alternativ können Sie sie einfach durchlaufen und ignorieren.