Wann und wie wurde der Doppelstrich (-) in Unix / Linux als Begrenzer für Optionen eingeführt?

49

Ich denke nicht, dass die Shell / Utilities in historischem Unix oder in etwas so "Neuem" wie 4.4BSD unterstützt werden, wenn ein Doppelstrich (oder zwei aufeinanderfolgende Bindestriche) als Begrenzer für das Ende von Optionen verwendet wird . Mit FreeBSD können Sie beispielsweise einen Hinweis sehen, der in den rm Hilfeseiten mit der Version 2.2.1 (1997) eingeführt wurde. Dies ist jedoch nur die Dokumentation für einen Befehl.

Wenn ich mir das älteste GNU-Fileutils- Changelog ansehe, das ich finden kann, sehe ich dieses 1 (leicht verändert):

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.

Dies ist älter als Linux . Es ist klar zu Konto für die Tatsache , dass Sie eine Datei mit einem Namen erstellen möchten die gleiche Anzahl von Ziffern als Zeit enthält Spezifikation (acht oder zehnstellige Dezimalzahl) - anstatt die Angabe einen Zeitstempels für eine bestehende Datei ...


  • Ist es also Posix.1, das den Doppelstrich ( --) als Begrenzer für das Ende von Optionen in Unix-Shells einführte ?
  • Hat alles damit angefangen, dass einige Leute touchin den frühen 90ern Ziffern in Dateinamen verwenden wollten und dies dann ein Jahrzehnt lang Stück für Stück nacheinander ging?
  • Worum geht es in dem temperamentvollen Kommentar im Changelog?
  • Wann wurde Leitlinie 10 ( Das Argument - sollte als Begrenzer für das Ende der Optionen akzeptiert werden. [...] ) in die POSIX Utility-Syntax eingeführt ?

1. Im Gegensatz dazu, dh das Dokumentieren der langen Optionen in allen Befehlen, die global verwendet werden, was nichts damit zu tun hat. Auf der anderen Seite können Sie Bezug auf das Trennzeichen sehen erscheinen in so etwas wie GNU rm.c im Jahr 2000 als Kommentar, bevor sie ausgesetzt 2005 (die an den Endverbraucher diagnose_leading_hyphen - Funktion). Dies ist jedoch alles viel später und handelt von einem sehr spezifischen Anwendungsfall.

Gilles 'SO - hör auf böse zu sein'
quelle
1
BSD4.3RENO hatte zumindest ein getoptunterstütztes --.
Stéphane Chazelas
@ StéphaneChazelas Sie haben auch einen Kommentar über getopt nicht mit dem Begrenzer der einzige api umgehen können zu sein. Bedeutet das, dass dies vorgesehen war und funktioniert hat, bevor es tatsächlich verwendet wurde? Ich fürchte, das ist mir ein Rätsel. Danke!
2
Es wurde wahrscheinlich von mehreren zufälligen Programmen ad hoc verwendet, aber ich denke, es wurde zum ersten Mal dokumentiert, als getoptes in den frühen 1980er Jahren geschrieben wurde. Wenn jemand das getopt-Papier von Uniforum '85 bekommen kann, könnte das Geschichte schreiben.
Mark Plotnick
2
@MarkPlotnick, eigentlich das Getopt wie es auf SysIII (1980) unterstützt --.
Stéphane Chazelas

Antworten:

38

Soweit ich das beurteilen kann, --beginnt die Verwendung als End-of-Options-Marker mit shund getoptin System III Unix (1980).

Nach dieser Geschichte der Bourne Shell-Familie erschien die Bourne Shell erstmals in Version 7 Unix (1979). Aber es gab keine Möglichkeit set, Optionen von Argumenten zu trennen . Die ursprüngliche Bourne-Shell könnte also Folgendes tun:

  • set -e - Exit-On-Error-Modus einschalten
  • set arg1 arg2 ...- setzt die Positionsparameter $1=arg1, $2=arg2etc.

Aber: set arg1 -e arg2würde Ihnen $1=arg1, $2=arg2und biegen Sie an der Ausfahrt-on-error . Hoppla.

System III Unix (1980) hat diesen Fehler behoben und eingeführt getopt. Laut getopt‚s Manpage :

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.

Soweit ich das beurteilen kann, ist das der erste Ort, an dem es erscheint.

Von da an scheinen andere Kommandos die --Konvention übernommen zu haben, um Mehrdeutigkeiten beim Parsen von Argumenten (wie die Beispiele mit touchund rmSie oben zitieren) in den wilden, standardlosen Tagen der 1980er Jahre aufzulösen .

Einige dieser schrittweisen Adoptionen wurden in POSIX.1 (1988) kodifiziert , woher der Changelog-Kommentar zum "POSIX-erforderlichen Kludge" stammt.

Erst mit POSIX.2 (1992) wurden die Utility Syntax Guidelines verabschiedet, die die berühmte Guideline 10 enthalten:

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.

Und hier geht es von einem "Kludge" zu einer universellen Empfehlung.

Wälder
quelle
Danke dass du dir die Zeit nimmst! Ich hatte getopt in meinen "Nachforschungen" größtenteils ignoriert, da ich nicht verstehe, warum diese Art von abstrahierter Nützlichkeit / Funktion erforderlich ist. Jetzt habe ich gelesen, dass dies irgendwann überarbeitet wurde (getopts) , um mit Leerzeichen usw. umzugehen, wie es sysv nicht getoptkonnte. Ich werde mehr darüber lesen! Danke noch einmal!
5
Wenn Sie nicht verstehen, warum ein Standarddienstprogramm zum Parsen von Befehlszeilenoptionen nützlich ist, haben Sie vielleicht nicht versucht, einen Shell-Parser für Befehlszeilenoptionen zu schreiben? Es ist eine Art Schmerz! Sicher wäre es schön, wenn ein anderes Tool dies für mich tun würde ... Denken Sie auch daran: 1980 gab es kein Python, kein Ruby, kein Java, kein Perl, kein PHP - auch C ++ musste noch erfunden werden, und das Die gesamte Idee von "Shell Scripting" war noch ziemlich neu. Die Idee eines Standard-Kommandozeilen-Parsers war also noch ziemlich neu!
Wwoods