2010-06-08 18 views
17

Nếu tôi có một dòng lệnh như:Làm thế nào tôi có thể cho phép tùy chọn xác định khi phân tích cú pháp args với getopt

my_script.pl -foo -WHATEVER 

Kịch bản của tôi biết về --foo, và tôi muốn getopt để thiết lập biến $opt_foo, nhưng tôi không biết bất cứ điều gì về -WHATEVER. Làm thế nào tôi có thể nói với Getopt để phân tích các tùy chọn mà tôi đã nói với nó, và sau đó nhận được phần còn lại của các đối số trong một biến chuỗi hoặc một danh sách?

Một ví dụ:

use strict; 
use warnings; 

use Getopt::Long; 

my $foo; 

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

print 'remaining options: ', @ARGV; 

Sau đó, phát hành

perl getopttest.pl -foo -WHATEVER

cho

 
Unknown option: whatever 
remaining options: 

Trả lời

20

Bạn cần phải cấu hình "pass_through" tùy chọn qua Getopt::Long::Configure("pass_through");

Sau đó, nó hỗ trợ tùy chọn thực tế (ví dụ thứ bắt đầu bằng "-" và nếu không có sự đặc biệt "-" delimiter để biểu thị kết thúc tùy chọn "thực") .

Dưới đây là perldoc quote:

  • pass_through (mặc định: vô hiệu hóa)

    Tùy chọn chưa được biết, không rõ ràng hoặc được cung cấp với một giá trị tùy chọn không hợp lệ được chuyển qua trong @ARGV thay vì được gắn cờ là lỗi. Điều này làm cho nó có thể viết các kịch bản lệnh wrapper mà chỉ xử lý một phần của các đối số dòng lệnh do người dùng cung cấp và chuyển các tùy chọn còn lại cho một số chương trình khác.

Dưới đây là một ví dụ

$ 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

Một ha, điều đó sẽ giải thích tại sao tôi không tìm thấy nó ... :) – Ether

+4

Tôi thấy nó hoàn toàn điên cuồng đọc về một số tùy chọn gọn gàng trên trang web perldoc và sau đó quay trở lại cài đặt Perl công ty mesoso của tôi và thấy rằng chính xác lựa chọn hoàn hảo Tôi đã tìm thấy yêu cầu một tụ điện thông, hoặc ít nhất một nâng cấp mô-đun CPAN – DVK

+1

Bạn có chắc 'pass_through' không có sẵn với 5.8? Tôi chỉ cần kiểm tra 'perldoc Getopt :: Long' cho 5.6.1 (và bạn nghĩ bạn là tiền sử lịch sử;)) và nó ở đó. – Zaid

1

Không phải các giá trị (chưa phân tích) còn lại chỉ đơn giản là bỏ lại phía sau trong @ARGV? Nếu nội dung thêm bạn bắt đầu với dấu gạch ngang, bạn sẽ cần phải chỉ ra sự kết thúc của danh sách tùy chọn với một --:

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

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

Sau đó gọi:

my_script.pl --foo -- --WHATEVER 

cho:

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

PS . Trong MooseX::Getopt, các tùy chọn "còn lại" từ dòng lệnh được đưa vào thuộc tính extra_argv dưới dạng arrayref - vì vậy tôi khuyên bạn nên chuyển đổi!

+0

Họ không phải là nếu họ trông giống như tùy chọn. Thay vào đó, một lỗi như 'Tùy chọn không xác định: WHATEVER' sẽ được cấp cho STDERR. –

+0

@ Robert: bình luận của bạn và chỉnh sửa của tôi vượt qua trong ether :) – Ether

+0

:] Thật vậy! Haha, tôi cũng đã thêm một ví dụ như thế vào câu hỏi. –

0

Tôi nghĩ câu trả lời ở đây, thật đáng buồn là "không, không có cách nào để thực hiện chính xác như bạn hỏi, sử dụng Getopt :: Long, không phân tích cú pháp @ARGV của riêng bạn". Ether có một cách giải quyết khá tốt. Đó là một tính năng như xa như hầu hết mọi người đang lo ngại rằng bất kỳ đối số tùy chọn giống như được bắt giữ như là một lỗi. Thông thường, bạn có thể làm

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

để chụp/ngăn các tùy chọn lẻ được chuyển, sau đó bạn có thể sửa người dùng khi sử dụng. Ngoài ra, bạn có thể đơn giản đi qua và bỏ qua chúng.

Các vấn đề liên quan