Kiedy i jak wprowadzono podwójną kreskę (-) jako ogranicznik końca opcji w systemach Unix / Linux?

49

Nie sądzę, aby powłoka / narzędzia w historycznym Uniksie ani w czymś tak „najnowszym” jak 4.4BSD obsługiwane przy użyciu podwójnego myślnika (lub dwóch kolejnych łączników) jako ogranicznika końca opcji . Z FreeBSD , można zobaczyć na przykład notatki wprowadzone w rm manpages z 2.2.1 wydaniu (1997). Ale to tylko dokumentacja dla jednego polecenia.

Patrząc na najstarszy dziennik zmian plików GNU, jaki mogę znaleźć, widzę ten 1 (nieco zmieniony):

Tue Aug 28 18:05:24 1990  David J. MacKenzie  (djm at albert.ai.mit.edu)

* touch.c (main): Don't interpret first non-option arg as a   <---
  time if `--' is given (POSIX-required kludge).  
* touch.c: Add long-named options.
* Many files: Include <getopt.h> instead of "getopt.h" since
  getopt.h will be in the GNU /usr/include.
* install.c: Declare some functions.
* touch.c, getdate.y, posixtime.y, mktime.c: New files, from bin-src.
* posixtime.y: Move year from before time to after it (but
  before the seconds), for 1003.2 draft 10.

To poprzedza Linuksa . Oczywiście należy wziąć pod uwagę fakt, że możesz chcieć utworzyć plik o nazwie zawierającej tę samą liczbę cyfr co specyfikacja czasu (osiem lub dziesięć cyfr po przecinku) - zamiast określać znacznik czasu dla istniejącego pliku ...


  • Czy to posix.1, który wprowadził podwójną kreskę ( --) jako ogranicznik końca opcji w powłokach uniksowych?
  • Czy to wszystko się zaczęło, ponieważ niektórzy ludzie chcieli używać cyfr w nazwach plików touchna początku lat 90., a potem to działało w sposób fragmentaryczny po jednym narzędziu na raz przez dekadę?
  • O czym jest porywający komentarz w dzienniku zmian?
  • Kiedy wytyczna 10 ( Argument - należy zaakceptować jako separator wskazujący koniec opcji. [...] ) wprowadzono do składni narzędzia POSIX ?

1. W przeciwieństwie do tego, tj. Dokumentowanie długich opcji we wszystkich komendach użycia globalnie, co nie jest powiązane. Z drugiej strony, można zobaczyć odniesienia do separatora pojawiają się w coś w rodzaju GNU rm.c w 2000 roku jako komentarz, zanim zostanie wystawiony do użytkownika końcowego w roku 2005 (w diagnose_leading_hyphen funkcji). Ale to wszystko znacznie później i dotyczy bardzo konkretnego przypadku użycia.

Gilles „SO- przestań być zły”
źródło
1
BSD4.3RENO przynajmniej miał getopttaki obsługiwany --.
Stéphane Chazelas
@ StéphaneChazelas też popełnił komentarz o getopt nie jest jedynym api w stanie poradzić sobie z separatora. Czy to oznacza, że ​​zostało to przewidziane i działało przed faktycznym użyciem? Obawiam się, że to jest poza mną. Dziękuję Ci!
2
Prawdopodobnie był używany doraźnie przez kilka losowych programów, ale myślę, że po raz pierwszy został udokumentowany, kiedy getoptzostał napisany na początku lat 80. Jeśli ktoś może dostać papier getopt z Uniforum '85, może to dać trochę historii.
Mark Plotnick
2
@MarkPlotnick, w rzeczywistości obsługuje getopt, jak znaleziono na SysIII (1980) --.
Stéphane Chazelas

Odpowiedzi:

38

O ile mogę powiedzieć, wykorzystanie --jako end-of-Options-markera zaczyna się shi getoptsystem Unix III (1980).

Zgodnie z tą historią rodziny Bourne Shell , Bourne Shell pojawił się po raz pierwszy w wersji 7 Unix (1979). Ale to nie ma drogę setdo oddzielenia opcje z argumentów . Oryginalna powłoka Bourne'a mogłaby:

  • set -e - włącz tryb wyjścia po błędzie
  • set arg1 arg2 ...- ustawia parametry pozycyjne $1=arg1, $2=arg2itd

Ale: set arg1 -e arg2nie daje $1=arg1, $2=arg2i włączyć wyjścia-on-błędu . Ups

System III Unix (1980) naprawił ten błąd i wprowadził go getopt. Według getopt„s stronie man :

NAME
   getopt - parse command options

SYNOPSIS
   set -- `getopt optstring $∗`

DESCRIPTION
   Getopt is used to break up options in command lines for easy parsing by
   shell procedures, and to check  for  legal  options.   Optstring  is  a
   string  of  recognized  option letters (see getopt(3C)); if a letter is
   followed by a colon, the option is expected to have an  argument  which
   may or may not be separated from it by white space.  The special option
   -- is used to delimit the end of the options.  Getopt will place --  in
   the  arguments  at  the  end  of  the  options, or recognize it if used
   explicitly.  The shell arguments ($1 $2 . . .) are reset so  that  each
   option  is  preceded  by a - and in its own shell argument; each option
   argument is also in its own shell argument.

O ile wiem, to pierwsze miejsce, w którym się pojawia.

Stamtąd wydaje się, że inne polecenia przyjęły --konwencję w celu rozwiązania niejasności analizowania argumentów (takich jak przykłady z touchi rmcytujesz powyżej) podczas dzikich, niestandardowych dni lat osiemdziesiątych.

Niektóre z tych fragmentarycznych adopcji zostały skodyfikowane w POSIX.1 (1988), stąd pochodzi komentarz dziennika zmian na temat „kludge wymaganego przez POSIX”.

Ale dopiero w POSIX.2 (1992) przyjęto Wytyczne dotyczące składni narzędzi , które zawierają słynną wytyczną 10:

Guideline 10:    The argument "--" should be accepted as a delimiter
                 indicating the end of options.  Any following
                 arguments should be treated as operands, even if they
                 begin with the '-' character.  The "--" argument
                 should not be used as an option or as an operand.

I od tego jest bycie „kludge” do uniwersalnej rekomendacji.

wwoods
źródło
Dziękuję Ci za poświęcenie czasu! Zasadniczo ignorowałem getopt w moich „badaniach”, ponieważ nie rozumiem, dlaczego taka abstrakcyjna użyteczność / funkcja jest wymagana. Teraz czytam, że w pewnym momencie zostało to przeprojektowane (getopts), aby poradzić sobie z pustkami itp., Ponieważ sysv getoptnie mógł tego zrobić. Przeczytam o tym więcej! Dzięki jeszcze raz!
5
Jeśli nie rozumiesz, dlaczego przydatne byłoby standardowe narzędzie do analizowania opcji wiersza polecenia, być może nie próbowałeś napisać parsera powłoki dla opcji wiersza polecenia? To rodzaj bólu! Na pewno byłoby miło, gdyby zrobiło to dla mnie inne narzędzie ... Pamiętaj też: w 1980 roku nie było Pythona, Ruby, Java, Perla, PHP - nawet C ++ jeszcze nie zostało wynalezione, a cały pomysł „skryptowania powłoki” był wciąż całkiem nowy. Pomysł standardowego analizatora składni wiersza poleceń był wciąż dość nowatorski!
wwoods,