2016-05-26 20 views
0

Ich verwende Getopt :: Long, um Optionen zu meinem Perl-Skript zu übergeben.Wie übergeben Sie obligatorische und optionale Befehlszeilenargumente an Perl-Skript?

Aber ich will, so etwas tun:

perl myScript mandatoryArgument1 -optionalArgument1=someValue 

ich das Skript möchte einen Fehler werfen, wenn mandatoryArgument1 fehlt. Wie kann das gemacht werden?

+0

Sie könnten [diesen Artikel] (http://perltricks.com/article/195/2015/10/21/Professional-scripts-are-a-snap-with-Getopt--Long/) nützlich finden. – jreisinger

Antwort

4

Aktualisieren   Beendete den zweiten Teil für, wenn das obligatorische Argument nicht benannt ist.


Die gute Getopt::Long hat speziell keinen Mechanismus dafür.

Sie können überprüfen, was obligatorisch ist, nachdem Sie die Argumente gelesen haben. Zum Beispiel

use warnings; 
use strict; 
use Getopt::Long; 

my $mandatoryArg; 
my $opt; 

# Read command-line arguments, exit with usage message in case of error 
if (not GetOptions('name=s' => \$mandatoryArg, 'flag' => \$opt)) { 
    usage(); 
    exit; 
} 
if (not defined $mandatoryArg) { 
    # print specific message, the generic usage message, and exit 
    print STDERR "Argument 'name' is mandatory"; 
    usage(); 
    exit; 
} 

# The program goes now ... $opt may or may have not been supplied 

sub usage { 
    print STDERR "Usage: $0 ..."; # full usage message 
} 

Also, wenn --name string nicht auf der Kommandozeile der $mandatoryArg und das Programm beendet undefiniert bleibt. Diese Variable benötigt keinen Standardwert, da dies obligatorisch ist.

Dies ist eine Skizze. Die Überprüfung und Verarbeitung von Argumenten ist oft viel aufwändiger.


Nach Re-Lektüre der Frage, die ich erkennen, dass die mandatoryArgument1 ohne einen Namen gegeben wurde. Ich würde empfehlen, dass mit Getopt::Long nur benannte Argumente verwendet werden. Es fügt nicht viel Tipparbeit hinzu.

Das Modul erlaubt jedoch, Argumente mit benannten Optionen an beliebiger Stelle in der Befehlszeile zu mischen. Siehe Option with other arguments in Dok.So können Sie das Programm als

script.pl --opt1 value1 unnamed_arg --opt2 value2 

Dann rufen nach GetOptions macht seinen Job, @ARGV enthält die Zeichenfolge unnamed_arg und Sie können es (oder herausfinden, dass sie nicht da ist). Die Verarbeitung von benannten Optionen durch GetOptions ist die gleiche wie oben.

my ($var1, $var2); 
if (not GetOptions(opt1 => \$var1, opt2 => \$var2)) { 
    usage(); 
    exit; 
}  
# All named options have been collected, all else left in @ARGV 
# Read the remaining argument(s) from @ARGV, or exit with message 

# This can get far more complicated if more than one is expected 
my $mandatoryArg1 = shift @ARGV || do { 
    print STDERR "Mandatory argument (description) is missing\n"; 
    usage(); 
    exit; 
}; 

Above Sie noch @ARGV von Hand zu verarbeiten haben, einmal gepflückt Getopt die genannten Argumente auf. Wenn es mehr als ein solches Argument gibt, müssen Sie ihre relative Position in der Befehlszeile strikt einhalten, und dies kann schwierig sein, da es davon abhängt, was der Benutzer physikalisch eingibt.

Während all das ist möglich Module wie Getopt existieren genau so, dass wir es nicht tun müssen.

+0

+1 für den letzten Satz! Ich habe einmal den Code eines Ignoranten geerbt, der die Option implementiert hat, sich selbst zu analysieren. Es war so ein Chaos! – PerlDuck

1

Mein Ansatz mit Getopt::Long:

sub help { print "Some help"; exit } 

sub main { 
    GetOptions(
     'file|f=s' => \(my $file = undef), 
     'tag|t=s' => \(my $tag = undef), 
     'help|h'  => \(my $printHelp = undef), 
    ); 

    help() if $printHelp; 
    help() unless $file; 

[...] 

} 

In diesem Fall wird die Option --file oder -f obligatorisch ist. Ich überprüfe, ob $file definiert ist, andernfalls bricht ich die Ausführung ab, indem ich die Hilfe des Programms drucke.

Ich würde nicht benannte Eingangsparameter in der Form --param=*value* mit nicht genannten Parameter mischen. Das heißt, Sie können @ARGV vor dem Aufruf Getopt::Long manipulieren und konfigurieren, um zu tun, was Sie gefragt haben, aber es ist verwirrend, zwei Arten von Eingabeparameter Philosophie für die Benutzer Ihres Skripts zu mischen.

#!/usr/bin/env perl 
use strict; 
use warnings; 
use feature qw{say}; 
use Carp; 
use Getopt::Long;  

sub main {  
    my $firstParam = shift @ARGV; 
    croak "Mandatory parameter not given" 
     if (!$firstParam || $firstParam =~ /^-/); 

    GetOptions(
     'file|f=s' => \(my $file = undef), 
     'tag|t=s' => \(my $tag = undef), 
    ); 


    say 'Mandatory: ', $firstParam; 
    say 'Optional $file: ', $file if $file; 
    say 'Optional $tag: ', $tag if $tag; 
} 

main(); 

Sie können es als ./test.pl mandatory -f file -t tag nennen:

Mandatory: mandatory                       
Optional $file: file                      
Optional $tag: tag 

werden Sie haben die Pflichtparameter (n) zu einer festen Position zu beschränken (in meinem Beispiel der ersten, wie in der Frage, aber es könnte die letzten auch sein).