Przetwarzanie argumentów wiersza poleceń odbywa się za pomocą wbudowanej tablicy @ARGV, która zawiera wszystkie parametry przekazane do skryptu podczas uruchamiania (z wyjątkiem samej nazwy skryptu). To podstawowy sposób dla wszelkich aplikacji Perl CLI, ale ma wiele niuansów związanych z typami danych, kodowaniem, rozdzielaniem parametrów i pułapkami autoodczytu plików.
Od pierwszych wersji Perl tablica @ARGV stanowiła standardowy "punkt wejścia" w argumenty uruchamiania, analogicznie do argv[] w C. Jednak Perl, będący językiem ogólnego przeznaczenia i zadania tekstowe, dodał wiele dodatkowych sztuczek — na przykład, wyrażenie <>, które jest "połączone" z zawartością @ARGV, pozwala na natychmiastowe odczytywanie plików wymienionych jako argumenty.
Trywialne odczytywanie @ARGV nadaje się tylko do prostych przypadków. W złożonych programach CLI pojawia się zadanie przetwarzania opcji (typu --help, -o plik). Tu proste odczytywanie danych po indeksach staje się niebezpieczne i niewygodne. Jeszcze trudniej jest z przetwarzaniem argumentów zawierających spacje, niestandardowe znaki lub o różnych kodowaniach. Dodatkowo, pojawiają się pytania z automatycznym otwieraniem plików przez operator <> i nieprzewidywalnym zachowaniem, jeśli elementy @ARGV są równe, na przykład "-" (stdin).
Odczytywanie prostych argumentów:
foreach my $arg (@ARGV) { print "Arg: $arg "; }
Zazwyczaj do opcji używa się specjalnego modułu Getopt::Long:
use Getopt::Long; my $help; GetOptions('help' => \$help);
Aby odczytać wszystkie pliki z @ARGV, zawartość plików można od razu czytać przez pętlę:
while (<>) { print; }
Co się stanie, jeśli jeden z argumentów wiersza poleceń zawiera tylko myślnik (-)?
W tym przypadku przy użyciu operatora <> Perl traktuje '-' jako standardowe wejście (stdin), a nie nazwę pliku.
perl script.pl - file.txt # Odczyt najpierw z stdin, potem z file.txt
Czy można bezpiecznie modyfikować @ARGV wewnątrz skryptu?
Tak, to standardowa praktyka w celu usunięcia już przetworzonych argumentów. Zazwyczaj po przetworzeniu opcji @ARGV pozostawia się tylko "czyste" nazwy plików lub nierozpoznane parametry.
Czy należy wykonywać kodowanie/dekodowanie podczas pracy z argumentami UTF-8 w @ARGV?
To zależy od lokalizacji i środowiska. Domyślnie Perl nie konwertuje kodowań @ARGV, a przyjmuje "jak jest". Dlatego, jeśli nazwy plików (lub parametry) zawierają znaki nie-ASCII, warto jawnie dekodować ciągi przy pomocy Encode, jeśli wymagana jest praca z nimi w Perl.
Narzędzie do analizy logów przyjmuje listę plików. Użytkownik przypadkowo podaje '-':
perl parse.pl - access.log
w wyniku czego program nagle zablokował się i czeka na wejście z klawiatury.
Plusy:
Minusy:
Program CLI odczytuje argumenty przez Getopt::Long, jednoznacznie przetwarza wszystkie opcje minusowe, pozostawiając w @ARGV tylko nazwy plików:
perl report.pl --input access.log --output report.txt
Plusy:
Minusy: