Obecnie piszę skrypt Bash, który ma następujące wymagania:
- powinien działać na wielu różnych platformach Unix / Linux
- powinien obsługiwać zarówno opcje krótkie, jak i (GNU)
Wiem, że getopts
byłby to preferowany sposób pod względem przenośności, ale AFAIK nie obsługuje długich opcji.
getopt
obsługuje długie opcje, ale BashGuide zdecydowanie zaleca:
Nigdy nie używaj getopt (1). getopt nie może obsługiwać pustych ciągów argumentów ani argumentów z osadzonymi białymi spacjami. Proszę zapomnij, że kiedykolwiek istniał.
Tak więc nadal istnieje możliwość ręcznego parsowania. Jest to podatne na błędy, generuje całkiem sporo kodu typu „płyta podstawowa” i muszę samodzielnie obsługiwać błędy ( getopt(s)
wydaje mi się, że same zajmują się obsługą błędów).
Więc jaki byłby preferowany wybór w tym przypadku?
bash
shell-script
options
user-interface
getopts
helpermethod
źródło
źródło
Odpowiedzi:
Jeśli musi być przenośny na wiele Uniksów, musisz trzymać się POSIX sh. A AFAIU nie ma po prostu innego wyboru, jak ręczne przetwarzanie argumentów.
źródło
getopt
vsgetopts
wydaje się być kwestią religijną. Co do argumentów przeciwkogetopt
w Bash FAQ :„
getopt
nie można obsłużyć ciągów pustych argumentów” wydaje się odnosić do znanego problemu z opcjonalnymi argumentami, który, jak się wydaje, wgetopts
ogóle nie obsługuje (przynajmniej z czytaniahelp getopts
Bash 4.2.24). Odman getopt
:Nie wiem, skąd pochodzi „
getopt
nie można [...] argumentować za pomocą osadzonych białych znaków”, ale przetestujmy to:test.sh:
biegać:
Wygląda na to, że sprawdzam i współpracuję, ale jestem pewien, że ktoś pokaże, jak całkowicie źle zrozumiałem zdanie. Oczywiście kwestia przenośności nadal obowiązuje; musisz zdecydować, ile czasu warto zainwestować w platformy ze starszą wersją Bash lub bez niej. Moja własna rada to stosowanie wytycznych YAGNI i KISS - rozwijaj tylko dla tych konkretnych platform, o których wiesz, że będą używane. Przenośność kodu powłoki zwykle spada do 100% w miarę upływu czasu programowania.
źródło
getopt
gdy cytowany tutaj temat jest specyficzny dla Linuksa. Zauważ, żegetopt
nie jest to częściąbash
, nie jest to nawet narzędzie GNU, aw systemie Linux jest dostarczane z pakietem util-linux.getopt
, tylko Linux AFAIK jest dostarczany z taką, która obsługuje długie opcje lub spacje w argumentach. Pozostałe obsłużyłyby tylko składnię Systemu V.getopt
to tradycyjne polecenie pochodzące z Systemu V na długo przed wydaniem Linuksa.getopt
nigdy nie był ustandaryzowany. Żaden z POSIX, Unix ani Linux (LSB) nigdy nie ustandaryzowałgetopt
polecenia.getopts
jest określony we wszystkich trzech, ale bez obsługi długich opcji.getopt
. Jest to smak linux-utils, jak wskazuje @ StéphaneChazelas. Posiada starsze opcje, które wyłączą opisaną powyżej składnię, w szczególności strona man stwierdza „GETOPT_COMPATIBLE zmusza getopt do użycia pierwszego formatu wywołania określonego w SYNOPSIS”. Jeśli jednak można oczekiwać, że systemy docelowe będą miały zainstalowany ten pakiet, jest to całkiemJest taki getopts_long napisany jako funkcja powłoki POSIX, którą możesz osadzić w skrypcie.
Pamiętaj, że Linux
getopt
(odutil-linux
) działa poprawnie, gdy nie jest w trybie tradycyjnym i obsługuje długie opcje, ale prawdopodobnie nie jest dla ciebie opcją, jeśli chcesz być przenośny na inne Uniksy.Najnowsze wersje ksh93 (
getopts
) i zsh (zparseopts
) mają wbudowaną obsługę parsowania długich opcji, które mogą być opcją dla Ciebie, ponieważ są one dostępne dla większości Uniksów (choć często nie są instalowane domyślnie).Inną opcją byłoby użycie
perl
i jegoGetopt::Long
moduł, które oba powinny być obecnie dostępne w większości Uniksów, albo przez napisanie całego skryptu,perl
albo po prostu wywołanie perla tylko w celu przeanalizowania opcji i podania wyodrębnionej informacji do powłoki. Coś jak:Zobacz,
perldoc Getopt::Long
co może zrobić i czym różni się od innych analizatorów opcji.źródło
Każda dyskusja na ten temat uwypukla opcję ręcznego pisania kodu parsującego - tylko wtedy możesz być pewien funkcjonalności i przenośności. Odradzam pisanie kodu, który można wygenerować i ponownie wygenerować za pomocą łatwych w użyciu generatorów kodu open source. Użyj Argbash , który został zaprojektowany, aby zapewnić ostateczną odpowiedź na Twój problem. Jest to dobrze udokumentowany generator kodu dostępny jako aplikacja wiersza poleceń , online lub jako obraz Docker .
getopt
Odradzam korzystanie z bibliotek bash, niektóre z nich używają (co sprawia, że nie można ich przenosić), a dołączenie do skryptu gigantycznego, nieczytelnego obiektu blob powłoki jest bardzo trudne.źródło
Możesz użyć
getopt
w systemach, które go obsługują i skorzystać z rezerwowych systemów, które nie obsługują.Na przykład
pure-getopt
jest zaimplementowany w czystym Bashu, aby zastępować GNUgetopt
.źródło