Chcę wywołać myscript
plik w ten sposób:
$ ./myscript -s 45 -p any_string
lub
$ ./myscript -h #should display help
$ ./myscript #should display help
Moje wymagania to:
getopt
tutaj, aby uzyskać argumenty wejściowe- sprawdź, czy
-s
istnieje, jeśli nie, zwróć błąd - sprawdź, czy wartość po
-s
znaku to 45 lub 90 - sprawdź, czy
-p
istnieje, a po nim ciąg wejściowy - jeśli użytkownik wejdzie
./myscript -h
lub właśnie./myscript
wyświetli pomoc
Do tej pory wypróbowałem ten kod:
#!/bin/bash
while getopts "h:s:" arg; do
case $arg in
h)
echo "usage"
;;
s)
strength=$OPTARG
echo $strength
;;
esac
done
Ale z tym kodem dostaję błędy. Jak to zrobić za pomocą Bash i getopt
?
-s
sprawiają, że pozycyjną argumentu./myscript 45 anystring
.$./myscript -s 45 -p any_string
-p
faktycznie jest opcją (to znaczy, twój program może kontynuować, jeśli nie jest obecny). W tym wypadku./myscript 45 -p any_string
. (Myślę, że togetopt
może obsłużyć mieszane opcje i argumenty pozycyjne, podczas gdybash
wbudowane poleceniegetopts
wymaga umieszczenia wszystkich argumentów pozycyjnych po opcjach.)Odpowiedzi:
Przykładowe przebiegi:
źródło
usage()
naprawdę powinien zwrócić 1?-h
jego pośrednictwem powinien zwrócić0
, po uderzeniu w nieistniejącą flagę powinien zwrócić>0
(dla uproszczenia nie rozróżniałem tych przypadków i nikt nie zmusza cię do wydrukowania tekstu użycia w drugim przypadku) . Widziałem programy, które zawsze wracają!= 0
, nawet w dalszym ciągu-h/--help
. Może powinienem zaktualizować fragment, jeśli ludzie używają go jako szablonu (mam nadzieję, że nie)?getopts
projekt ( '), nie ma czegoś takiego jak „opcjonalne argumenty”getopts
. Analizator składni po prostu nie-p
może ustalić , czy następny token jest argumentem dla bieżącej opcji, czy też samą opcją, ponieważ może być zamierzoną wartością. Państwo może włamać się wokół tego, jeśli absolutnie wiedzieć, że parametr opcja nie może wyglądać innej ważnej opcji, tak, ale można powiedzieć, że jest powód opcjonalne argumenty nie są zdefiniowane w POSIX.bash
leksykowi w identyfikowaniu zmiennych. W wielu przypadkach są niepotrzebne, a fakt, że zawsze ich używam, jest kwestią osobistego stylu kodowania. Dla mnie łatwiej (i ładniej) jest po prostu zawsze ich używać zamiast zapamiętywać zasady analizowania w odniesieniu do dwuznaczności. Prawie to samo, dlaczego ktoś pisałbyif (foo) { bar; }
zamiastif (foo) bar;
w języku C (estetyka i / lub unikanie głupich błędów).Problem z oryginalnym kodem polega na tym, że:
h:
oczekuje parametru tam, gdzie nie powinien, więc zmień go na justh
(bez dwukropka)-p any_string
, musisz dodaćp:
do listy argumentówZasadniczo
:
po opcji oznacza, że wymaga argumentu.Podstawowa składnia
getopts
to (patrzman bash
:):gdzie:
OPTSTRING
jest łańcuchem z listą oczekiwanych argumentów,h
- sprawdź opcję-h
bez parametrów; podaje błąd w nieobsługiwanych opcjach;h:
- sprawdź opcję za-h
pomocą parametrem; podaje błędy w nieobsługiwanych opcjach;abc
- Sprawdź opcje-a
,-b
,-c
; podaje błędy w nieobsługiwanych opcjach;:abc
- Sprawdź opcje-a
,-b
,-c
; cisze błędy w nieobsługiwanych opcjach;Uwagi: Innymi słowy, dwukropek przed opcjami umożliwia obsługę błędów w kodzie. Zmienna będzie zawierać
?
w przypadku nieobsługiwanej opcji,:
w przypadku braku wartości.OPTARG
- jest ustawiony na bieżącą wartość argumentu,OPTERR
- wskazuje, czy Bash powinien wyświetlać komunikaty o błędach.Tak więc kod może być:
Przykładowe użycie:
Zobacz: Mały poradnik getopts na Bash Hackers Wiki
źródło
usage() { echo "$0 usage:" && grep "[[:space:]].)\ #" $0 | sed 's/#//' | sed -r 's/([a-z])\)/-\1/'; exit 0; }
. Uwzględnia tylko jeden znak spacji przed opcją litery, usuwa znak # z komentarza i wstawia znak „-” przed opcją litery, dzięki czemu jest bardziej zrozumiały dla polecenia.:
właściwego prawa, dopóki nie zobaczyłem tych notatek. Musimy dodać a:
do opcji, w których oczekujemy argumentu.Posługiwać się
getopt
Dlaczego getopt?
Aby przeanalizować złożone argumenty wiersza polecenia, aby uniknąć zamieszania i wyjaśnić opcje, które analizujemy, aby czytelnik poleceń mógł zrozumieć, co się dzieje.
Co to jest getopt?
getopt
służy do dzielenia (parsowania) opcji w wierszach poleceń w celu łatwego parsowania według procedur powłoki oraz do sprawdzania legalnych opcji. Korzysta z GNUgetopt(3)
procedury .getopt
może mieć następujące typy opcji.Uwaga: W tym dokumencie podczas wyjaśniania składni:
JAK KORZYSTAĆ
getopt
?Składnia: pierwsza forma
Przykłady:
Tutaj h, v, t to opcje, a -h -v -t to sposób, w jaki opcje powinny być podawane w wierszu poleceń.
W opcjonalnym parametrze wartość nie może mieć separacji białych znaków z opcją. Zatem w przykładzie „-t123” -t to opcja 123 to wartość.
Składnia: druga forma
Tutaj po getopt podzielony jest na pięć części
Przykłady
Składnia: trzecia forma
Tutaj po getopt podzielony jest na pięć części
Przykłady
GETOPT_OPTIONS
getopt_options zmienia sposób, w jaki analizowane są parametry wiersza poleceń.
Poniżej znajdują się niektóre z opcji getopt_options
Opcja: -l lub --długie opcje
Na przykład
--name=Karthik
jest długą opcją wysyłaną w wierszu polecenia. W getopt użycie długich opcji jest podobnePonieważ nazwa: jest określona, opcja powinna zawierać wartość
Opcja: -a lub - alternatywna
Przykład, zamiast
--name=Karthik
możesz użyć po prostu-name=Karthik
Kompletny przykład skryptu z kodem:
Uruchamianie tego pliku skryptu:
źródło
Przykład zapakowany w
getopt
(moja dystrybucja/usr/share/getopt/getopt-parse.bash
), wygląda tak, jakby obejmował wszystkie twoje przypadki:źródło
Wiem, że już na to odpowiedziano, ale dla nagrania i dla każdego, kto ma takie same wymagania jak ja, postanowiłem opublikować tę powiązaną odpowiedź. Kod jest zalewany komentarzami wyjaśniającymi kod.
Zaktualizowana odpowiedź:
Zapisz plik jako
getopt.sh
:Następnie możesz użyć tego w następujący sposób:
Stara odpowiedź:
Niedawno musiałem zastosować ogólne podejście. Natknąłem się na to rozwiązanie:
Nie przetestowałem tego z grubsza, więc mogłem mieć tam kilka błędów.
źródło
getopts
funkcji, dodajlocal OPTIND OPTARG
do funkcjigetopts
Przykład POSIX 7
Warto również sprawdzić przykład ze standardu: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/getopts.html
A potem możemy to wypróbować:
Testowany w Ubuntu 17.10,
sh
jest kreską 0.5.8.źródło
„getops” i „getopt” są bardzo ograniczone. Chociaż „getopt” sugeruje się, aby w ogóle nie był używany, oferuje długie opcje. Gdzie jako „getopts” dopuszcza tylko opcje pojedynczych znaków, takie jak „-a” „-b”. Istnieje kilka innych wad podczas korzystania z jednego z nich.
Napisałem więc mały skrypt, który zastępuje „getopts” i „getopt”. To początek, prawdopodobnie można by go znacznie poprawić.
Aktualizacja 08-04-2020 : Dodałem obsługę łączników, np. „--Package-name”.
źródło