2010-06-08 12 views
17

Jeśli mam linii poleceń jak:Jak mogę pozwolić opcje niezdefiniowane podczas analizowania args z Getopt

my_script.pl -foo -WHATEVER 

Mój skrypt wie o --foo i chcę Getopt ustawić zmienną $opt_foo, ale nie wiem cokolwiek o -WHATEVER. Jak mogę powiedzieć Getoptowi, aby przeanalizował opcje, o których mówiłem, a następnie uzyskać pozostałe argumenty w zmiennej łańcuchowej lub liście?

Przykład:

use strict; 
use warnings; 

use Getopt::Long; 

my $foo; 

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

print 'remaining options: ', @ARGV; 

Następnie wydawanie

perl getopttest.pl -foo -WHATEVER

daje

 
Unknown option: whatever 
remaining options: 

Odpowiedz

20

Musisz skonfigurować „pass_through” opcji poprzez Getopt::Long::Configure("pass_through");

Następnie wspierać rzeczywiste opcje (np rzeczy zaczynające się od „-” i bez „-” specjalnego separatora oznaczać koniec „prawdziwych” opcji) .

Oto perldoc cytat:

  • pass_through (domyślnie: wyłączone)

    opcji, które są nieznane, niejednoznaczne lub dostarczone z niepoprawną wartość opcji są przepuszczane przez w @ARGV zamiast być oznaczone jako błędy. Dzięki temu można pisać skrypty opakowujące, które przetwarzają tylko część podanych przez użytkownika argumentów wiersza poleceń, i przekazują pozostałe opcje do innego programu.

Oto przykład

$ 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

Ha, to by wyjaśniało, dlaczego go nie znalazłem ... :) – Ether

+4

Uważam, że jest to całkowicie irytujące czytanie o jakiejś fajnej opcji na perldoc stronie internetowej, a następnie wracam do mojej mesosoicznej korporacyjnej instalacji Perla i stwierdzam, że dokładnie idealna opcja Znalazłem wymaga kondensatora strumienia lub przynajmniej uaktualnienia modułu CPAN – DVK

+1

Czy jesteś pewien, że 'pass_through' nie jest dostępne z 5.8? Właśnie sprawdziłem 'perldoc Getopt :: Long' dla 5.6.1 (i myślałeś, że jesteś prehistoryczny;)) i to jest. – Zaid

1

nie są pozostałe (nieprzetworzonej) wartości po prostu pozostawione w @ARGV? Jeśli dodatkowo zawartość zaczyna się od myślnika, trzeba będzie wskazać koniec listy opcji z --:

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

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

następnie wywołanie:

my_script.pl --foo -- --WHATEVER 

daje:

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

PS . W MooseX::Getopt, "pozostałe" opcje z wiersza poleceń są umieszczane w atrybucie extra_argv jako arrayref - więc polecam konwersję!

+0

Nie są one, jeśli wyglądają opcji. Zamiast tego błąd typu "Nieznana opcja: WHATEVER" zostanie wysłany do STDERR. –

+0

@Robert: Twój komentarz i moja edycja zostały skrzyżowane w eterze :) – Ether

+0

:] Rzeczywiście! Haha, dodałem również taki przykład do pytania. –

0

Myślę, że odpowiedź tutaj, niestety, brzmi: "nie, nie ma sposobu, aby to zrobić dokładnie tak, jak pytasz, używając Getopt :: Long, bez samodzielnego analizowania @ARGV". Eter ma przyzwoite obejście. Jest to funkcja, o ile większość ludzi obawia się, że jakikolwiek argument podobny do opcji jest uchwycony jako błąd. Zwykle można wykonać w celu przechwycenia/uniemożliwienia przekazywania nieparzystych opcji, a następnie można poprawić użytkownika podczas użytkowania. Możesz też po prostu przejść i zignorować je.

Powiązane problemy