Dlaczego można pominąć spacje między opcjami i parametrami?


16

Na przykład:

xargs -n 1

jest taki sam jak

xargs -n1

Ale jeśli spojrzysz na stronę man , opcja jest wymieniona jako -n max-args, co oznacza, że ​​przestrzeń ma zostać zachowana. Nie ma nic w skróconej formie -n max-args .

Dzieje się tak również w przypadku wielu innych narzędzi systemu Linux.

Jak to się nazywa w systemie Linux? Czy wszystkie narzędzia obsługują skróconą formę (ale nigdy nie dokumentują jej na stronie podręcznika)?


1
12.1.2.a to część historii; Przysięgam, że jest już dobre pytanie na ten temat, ale jeszcze go nie znalazłem.

2
@drewbenn inne pytanie, o którym myślisz, mogło być moje: unix.stackexchange.com/q/188046/41515

Odpowiedzi:


12

Kiedy piszesz bit parsowania wiersza poleceń swojego kodu, określasz, które opcje przyjmują argumenty, a które nie. Na przykład w skrypcie powłoki akceptującym -hopcję (na przykład pomoc) i -aopcję, która powinna przyjąć argument, robisz

opt_h=0     # default value
opt_a=""

while getopts 'a:h' opt; do
    case $opt in
        h)  opt_h=1 ;;
        a)  opt_a="$OPTARG" ;;
    esac
done

echo "h: $opt_h"
echo "a: $opt_a"

a:hBit mówi „Czekam analizować dwie opcje, -ai -h, i -apowinna podjąć argument” (jest to :po ato mówi parser który -apobiera argumentu).

Dlatego nigdy nie ma dwuznaczności, gdzie kończy się opcja, gdzie zaczyna się jej wartość, a gdzie zaczyna się kolejna.

Uruchamianie:

$ bash test.sh -h -a hello
h: 1
a: hello

$ bash test.sh -h -ahello
h: 1
a: hello

$ bash test.sh -hahello
h: 1
a: hello

Właśnie dlatego przez większość czasu nie powinieneś pisać własnego parsera wiersza poleceń do analizowania opcji.

W tym przykładzie jest tylko jeden przypadek, który jest trudny. Analiza zwykle kończy się przy pierwszej opcji, więc gdy w wierszu polecenia masz elementy wyglądające jak opcje:

$ bash test.sh -a hello -world
test.sh: illegal option -- w
test.sh: illegal option -- o
test.sh: illegal option -- r
test.sh: illegal option -- l
test.sh: illegal option -- d
h: 0
a: hello

Następujące rozwiązuje, że:

$ bash test.sh -a hello -- -world
h: 0
a: hello

Te --sygnały końca opcji wiersza poleceń, a -worldbit zostaje w programie robić co chce z (to jest w jednej ze zmiennych pozycyjnych).

Tak przy okazji, usuwasz plik z myślnikiem na początku jego nazwy za pomocą rm.

EDYCJA :

Narzędzia napisane w wywołaniu C getopt()(zadeklarowane w unistd.h), które działają prawie tak samo. W rzeczywistości, wszyscy wiemy, bashfunkcja getoptsmoże być realizowana za pomocą wywołanie funkcji biblioteki C getopt(). Perl, Python i inne języki mają podobne biblioteki parsujące wiersze poleceń i najprawdopodobniej przeprowadzają parsowanie w podobny sposób.

Niektóre z tych getopti getoptpodobnych procedur bibliotecznych obsługują również „długie” opcje. Są one zwykle poprzedzone podwójnym myślnikiem ( --), a długie opcje, które pobierają argumenty, często robią to po znaku równości, na przykład --block-size=SIZEopcja [niektóre implementacje] dunarzędzia (które pozwala również na -B SIZEokreślenie tej samej rzeczy).

Powodem, dla którego podręczniki są często pisane, aby pokazać odstęp między krótkimi opcjami i ich argumentami, jest prawdopodobnie czytelność.

EDYCJA : Naprawdę stare narzędzia, takie jak ddi tarnarzędzia, mają przed sobą opcje bez myślników. Wynika to wyłącznie z przyczyn historycznych i dla zachowania zgodności z oprogramowaniem, które polega na tym, że działają w ten właśnie sposób. tarNarzędzie zyskał zdolność do podejmowania opcje z kreskami w ostatnich czasach. Podręcznik BSD do tarwywoływania opcji w starym stylu dla „flag pakietowych”.


Ta funkcja może wydawać się łatwa do wdrożenia w skryptach bash. Ale myślę, że większość narzędzi jest napisana w C (a następnie skompilowana do plików binarnych), a nie bash. Dlaczego te narzędzia implementują tę funkcję?
J.Joe

@ J.Joe Ponieważ dzwonią getopt()(deklarowane w unistd.h), co robi to samo.
Kusalananda

2
Tak, masz rację. Odniesienia . To rozwiązuje również kolejną zagadkę, że opcje można łączyć -a -b=== -ab
J.Joe

1
Opcjonalne argumenty dla flag stworzyłyby niejednoznaczność, więc nie można ich łączyć (jeśli -ama opcjonalny argument, -abto nie to samo, co -a -b). GNU getopt nie zatrzymuje przetwarzania flag po spotkaniu z nie-flagą: zamiast tego (domyślnie), zamiast tego przetasowuje flagi na przód argv.
ilkkachu

@ilkkachu Dzięki za wyjaśnienie. Mogę zaktualizować swoją odpowiedź później.
Kusalananda

4

xargsjest jednym z narzędzi POSIX. Jak skomentował @drewbenn, POSIX dokumentuje zachowanie parsowania opcji dla większości swoich narzędzi do dopasowania getopt, z pewnymi tolerancjami dla innych implementacji, mówiąc w 12.1 Składnia argumentu narzędzia :

Ta sekcja opisuje składnię argumentów standardowych narzędzi i wprowadza terminologię stosowaną w POSIX.1-2008 do opisywania argumentów przetwarzanych przez narzędzia.

W POSIX.1-2008 do opisu składni argumentów narzędzia używana jest specjalna notacja. O ile nie zaznaczono inaczej , wszystkie opisy programów narzędziowych używają tej notacji, którą ilustruje ten przykład (patrz Proste polecenia XCU ):

i kończąc z

Zaleca się, aby wszystkie przyszłe narzędzia i aplikacje korzystały z tych wytycznych w celu zwiększenia przenośności użytkownika. Fakt, że niektórych historycznych narzędzi nie można było zmienić (aby uniknąć zepsucia istniejących aplikacji), nie powinien powstrzymywać tego przyszłego celu.

W POSIX (pamiętaj, że obejmuje on tylko najczęściej używane narzędzia), istnieją wyjątki, które przekazują operandy, które byłyby opcjami w innych narzędziach jako parametry pozycyjne lub parametry o specjalnej składni :

POSIX pozwala na opcjonalne wartości opcji:

Argumenty opcji są oddzielone od ich opcji <blank>znakami, z wyjątkiem sytuacji, gdy argument-opcji jest ujęty w notacji '['i ']'oznacza, że ​​jest opcjonalny.

Nie pamiętam, które narzędzia POSIX używają tej funkcji. Ncurses tici infocmpnarzędzia używają tej funkcji dla poziomów opcji -v(pełne / debugowanie).

Konkretny punkt, o który pytałeś, jest szczegółowo opisany w pozostałej części tego akapitu, w kilku wierszach.

Przed POSIX-em niektóre implementacje pszaakceptowanych opcji bez łącznika wiodącego. Opis POSIX nie wspomina o tym w opisie narzędzia ani w uzasadnieniu składni:

Oprócz POSIX istnieją implementacje długich opcji (takie jak GNU getopt_long lub X Toolkit ), wykorzystujące różne sposoby oddzielania lub łączenia wartości opcji z opcją. Na przykład można zastosować interpunkcję:

--option=value
--option value

W zależności od implementacji podwójny myślnik może / nie może być użyty do odróżnienia długich opcji od krótkich (getopt): Lynx i X Toolkit używają pojedynczego myślnika; Na przykład GNU getopt_longużywa podwójnego myślnika. Można również +użyć a, aby wskazać, że opcja jest zanegowana.

Opis POSIX nie wydaje się wymieniać żadnego z nich, ale na pewno je spotkasz.


Czy -option=valuema być --option=value? (Format długiej opcji, dwa myślniki na początku zamiast jednego)
J.Joe

Kilka starszych narzędzi korzysta z długich opcji pojedynczego myślnika (-opcja), ale są one w dużej mierze przestarzałe dla nowych skryptów i programów. Użyj pojedynczego myślnika dla krótkich opcji obsługiwanych przez getopt. Prawie wszystkie nowe skrypty i programy używają opcji podwójnego kreskowania. Wiele obsługuje również ekwiwalenty krótkich opcji pojedynczego myślnika dla najczęściej używanych. Długie opcje sprawiają, że kod skryptu jest znacznie bardziej samodokumentujący, wymagający mniej komentarzy.
DocSalvager,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.