Quando e come è stato introdotto il doppio trattino (-) come fine del delimitatore di opzioni in Unix / Linux?


49

Non credo che la shell / utility in Unix storico né in qualcosa di "recente" come 4.4BSD supportato usando un trattino doppio (o due trattini consecutivi) come fine del delimitatore di opzioni . Con FreeBSD , ad esempio, puoi vedere una nota introdotta nelle rm manpage con la versione 2.2.1 (1997). Ma questa è solo la documentazione per un comando.

Guardando più antichi fileutils GNU ChangeLog posso trovare, vedo questo 1 (leggermente modificato):

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.

Questo precede Linux . È chiaramente da considerare il fatto che potresti voler creare un file con un nome contenente lo stesso numero di cifre di una specifica temporale (numero decimale di otto o dieci cifre) - piuttosto che specificare un timestamp per un file esistente ...


  • Quindi è posix.1 che ha introdotto il doppio trattino ( --) come fine del delimitatore di opzioni nelle shell Unix?
  • Tutto è iniziato perché alcune persone volevano usare le cifre nei nomi dei file con touchnei primi anni '90 e poi questo è andato avanti in modo frammentario un'utilità alla volta per un decennio ??
  • Di cosa parla il vivace commento nel log delle modifiche?
  • Quando è stata accolta la linea guida 10 ( L'argomento - come delimitatore che indica la fine delle opzioni. [...] ) alla sintassi dell'utilità POSIX ?

1. Al contrario di ciò, vale a dire documentare le opzioni lunghe in tutti i comandi utilizzate a livello globale, il che non è correlato. D'altra parte, si può vedere riferimento al delimitatore apparire in qualcosa di simile GNU rm.c nel 2000 come un commento, prima di essere esposti per l'utente finale nel 2005 (la diagnose_leading_hyphen funzioni). Ma questo è tutto molto più tardi e riguarda un caso d'uso molto specifico.


1
BSD4.3RENO aveva almeno un getoptsupporto supportato --.
Stéphane Chazelas,

@ StéphaneChazelas Hai anche fatto un commento su getopt non essendo l'unica api in grado di gestire il delimitatore. Ciò significa che questo era stato previsto e funzionato prima che fosse effettivamente utilizzato ?? Temo che questo sia oltre me. Grazie!

2
Probabilmente è stato utilizzato su base ad hoc da diversi programmi casuali, ma penso che sia stato documentato per la prima volta quando è getoptstato scritto nei primi anni '80. Se qualcuno può ottenere il documento getopt da Uniforum '85, questo potrebbe dare un po 'di storia.
Mark Plotnick,

2
@MarkPlotnick, in realtà la getopt come si trova sui supporti SysIII (1980) --.
Stéphane Chazelas,

Risposte:


38

Per quanto ne so, l'uso di --come marker di fine opzioni inizia con she getoptin System III Unix (1980).

Secondo questa storia della famiglia Bourne Shell , la Bourne Shell apparve per la prima volta nella versione 7 Unix (1979). Ma non aveva modo setdi separare le opzioni dagli argomenti . Quindi la shell Bourne originale potrebbe fare:

  • set -e - attiva la modalità di uscita all'errore
  • set arg1 arg2 ...- imposta i parametri posizionali $1=arg1, $2=arg2e così via

Ma: set arg1 -e arg2darebbe $1=arg1, $2=arg2e attivare l'uscita-on-error . Ops.

System III Unix (1980) risolto quel bug e introdotto getopt. Secondo getoptla pagina man di :

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.

Per quanto ne so, è il primo posto in cui appare.

Da lì, sembra che altri comandi abbiano adottato la --convenzione per risolvere argomenti che analizzano le ambiguità (come gli esempi con touche rmcitati sopra) durante i giorni selvaggi e senza standard degli anni '80.

Alcune di queste adozioni frammentarie sono state codificate in POSIX.1 (1988), da cui proviene il commento del changelog sul "kludge richiesto da POSIX".

Ma non è stato fino a POSIX.2 (1992) che sono state adottate le Linee guida per la sintassi delle utility , che contengono le famose Linee guida 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.

Ed è qui che va dall'essere un "kludge" a una raccomandazione universale.


Grazie per aver dedicato del tempo! Nella mia "ricerca" avevo principalmente ignorato getopt poiché non capivo perché fosse necessario quel tipo di utilità / funzione astratta. Ora ho letto che questo è stato riprogrammato (getopts) ad un certo punto per occuparsi di spazi vuoti ecc. Come sysv getoptnon poteva. Ne leggerò di più! Grazie ancora!

5
Se non capisci perché un'utilità standard per l'analisi delle opzioni della riga di comando sarebbe utile, forse non hai provato a scrivere un parser di shell per le opzioni della riga di comando? È una specie di dolore! Sarebbe bello se qualche altro strumento lo facesse per me ... Inoltre, tieni presente: nel 1980 non c'erano Python, Ruby, Java, Perl, PHP - anche il C ++ doveva ancora essere inventato, e il l'intera idea di "shell scripting" era ancora piuttosto nuova. Quindi l'idea di un parser standard da riga di comando era ancora piuttosto innovativa!
Wwoods,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.