Die Verarbeitung von Befehlszeilenargumenten ist eine grundlegende Aufgabe für Perl-Programme. Historisch gesehen hat Perl die Variable @ARGV bereitgestellt, um auf die an das Skript übergebenen Argumente zuzugreifen. Das Problem ist, dass komplexe Szenarien Flags und Schlüssel-Wert-Parameter enthalten können, was eine manuelle Analyse des Arrays @ARGV erfordert. Bei falscher Herangehensweise können Parameter falsch verarbeitet, erforderliche Werte übersehen oder zusätzliche verarbeitet werden, was zu Fehlern in der Logik des Programms führt.
Die Lösung besteht darin, eine systematische Verarbeitung zu verwenden: Iteration durch @ARGV, Analyse des Inhalts, Verarbeitung von Schlüsseln und deren Werten.
Beispielcode:
my %args; while (my $arg = shift @ARGV) { if ($arg =~ /^--(\w+)=?(.*)/) { my ($key, $val) = ($1, $2); if ($val eq '' && @ARGV) { $val = shift @ARGV; # nächster Wert } $args{$key} = $val eq '' ? 1 : $val; } else { push @{$args{'_free'}}, $arg; } } print "Got foo: $args{foo} " if exists $args{foo};
Schlüsselfeatures:
Was passiert, wenn das Argument in der Form '--flag value' und nicht '--flag=value' übergeben wird?
Wenn nur die Trennung durch '=' verarbeitet wird, ist der Wert eine leere Zeichenkette, und das nächste Element des Arrays wird als eigenständiges Argument ignoriert. Die Lösung ist, beide Varianten beim Parsen zu berücksichtigen:
if ($arg =~ /^--(\w+)=?(.*)/)
und wenn $val leer ist, das nächste Element zu nehmen.
Wie verhält sich Perl mit Argumenten, die Leerzeichen enthalten?
Perl trennt Argumente innerhalb von @ARGV nicht durch Leerzeichen; dies erfolgt vollständig durch die Shell. Daher wird "--foo=bar baz" als zwei verschiedene Elemente behandelt, es sei denn, die Zeichenkette wird in der Befehlszeile in Anführungszeichen gesetzt. Dies ist zu beachten, und die Benutzer sollten immer aufgefordert werden, Leerzeichen zu maskieren.
Kann @ARGV mit shift modifiziert werden, ohne die ursprünglichen Argumente zu verlieren?
Shift verändert das Array selbst, die ursprüngliche Liste der Argumente kann nicht wiederhergestellt werden. Wenn der ursprüngliche Inhalt von @ARGV erhalten bleiben soll, muss es im Voraus dupliziert werden:
my @original_argv = @ARGV;
Das Skript verarbeitete nur Schlüssel der Form '--foo=bar' und ignorierte '--foo bar', was zu einem Fehler führte, wenn der Wert fehlte.
Vorteile:
Nachteile:
Es wurde die Verarbeitung beider Syntaxen und die Überprüfung der Länge von @ARGV hinzugefügt, Flags und Schalter wurden erlaubt.
Vorteile:
Nachteile: