¿Cuándo y cómo se introdujo el guión doble (-) como delimitador de fin de opciones en Unix / Linux?


49

No creo que el shell / utilidades en Unix histórico ni en algo tan "reciente" como 4.4BSD sea compatible con un guión doble (o dos guiones consecutivos) como final delimitador de opciones . Con FreeBSD , puede ver, por ejemplo, una nota introducida en las rm páginas de manual con la versión 2.2.1 (1997). Pero esto es solo la documentación para un comando.

Mirando el registro de cambios de archivos de GNU más antiguo que puedo encontrar, veo esto 1 (ligeramente alterado):

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.

Esto es anterior a Linux . Claramente es para tener en cuenta el hecho de que es posible que desee crear un archivo con un nombre que contenga el mismo número de dígitos que una especificación de tiempo (número decimal de ocho o diez dígitos), en lugar de especificar una marca de tiempo para un archivo existente ...


  • Entonces, ¿es posix.1 que introdujo el doble guión ( --) como un fin delimitador de opciones en shells de Unix?
  • ¿Comenzó todo esto porque algunas personas querían usar dígitos en los nombres de archivo a touchprincipios de los 90 y luego esto continuó de manera gradual, una utilidad a la vez durante una década?
  • ¿De qué se trata el enérgico comentario en el registro de cambios?
  • ¿Cuándo se introdujo la directriz 10 ( El argumento - debería aceptarse como un delimitador que indica el final de las opciones. [...] ) a la sintaxis de la utilidad POSIX ?

1. A diferencia de esto, es decir, documentar las opciones largas en todos los comandos de uso a nivel mundial, lo que no está relacionado. Por otro lado, puede ver que la referencia al delimitador aparece en algo como GNU rm.c en 2000 como un comentario, antes de exponerse al usuario final en 2005 (la función diagnostose_leading_hyphen ). Pero todo esto es mucho más tarde y se trata de un caso de uso muy específico.


1
BSD4.3RENO al menos tenía un getoptsoporte --.
Stéphane Chazelas

@ StéphaneChazelas También hizo un comentario acerca de que getopt no es el único capaz de manejar el delimitador. ¿Significa eso que esto había sido provisto y trabajado antes de que realmente fuera utilizado? Me temo que esto está más allá de mí. ¡Gracias!

2
Probablemente fue utilizado ad hoc por varios programas aleatorios, pero creo que se documentó por primera vez cuando getoptse escribió a principios de la década de 1980. Si alguien puede obtener el papel getopt de Uniforum '85, eso podría dar algo de historia.
Mark Plotnick

2
@ MarkPlotnick, en realidad es compatible con el getopt que se encuentra en SysIII (1980) --.
Stéphane Chazelas

Respuestas:


38

Por lo que puedo decir, el uso de --como marcador de fin de opciones comienza con shy getopten System III Unix (1980).

Según esta historia de la familia Bourne Shell , Bourne Shell apareció por primera vez en la Versión 7 Unix (1979). Pero no tuvo un camino para setque separe las opciones de argumentos . Entonces, el shell Bourne original podría hacer:

  • set -e - activar el modo de salida en caso de error
  • set arg1 arg2 ...- establece los parámetros posicionales $1=arg1, $2=arg2, etc.

Pero: set arg1 -e arg2le daría $1=arg1, $2=arg2y activar la salida-on-error . Whoops

System III Unix (1980) reparó ese error y lo introdujo getopt. De acuerdo con getoptla página del manual de :

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.

Por lo que puedo decir, ese es el primer lugar que aparece.

A partir de ahí, parece que otros comandos adoptaron la --convención para resolver las ambigüedades de análisis de argumentos (como los ejemplos con touchy que rmusted cita arriba) a lo largo de los días salvajes y sin estándar de la década de 1980.

Algunas de estas adopciones poco sistemáticas se codificaron en POSIX.1 (1988), que es de donde proviene el comentario del registro de cambios sobre el "kludge requerido por POSIX".

Pero no fue hasta POSIX.2 (1992) que se adoptaron las Pautas de sintaxis de utilidades , que contienen la famosa Pauta 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.

Y ahí es donde pasa de ser un "error" a una recomendación universal.


¡Gracias por tomarse el tiempo! Casi había ignorado getopt en mi "investigación" ya que no entiendo por qué se requiere ese tipo de utilidad / función abstraída. Ahora leí que esto fue rediseñado (getopts) en algún momento para tratar con espacios en blanco, etc., ya que los sysv getoptno podían. ¡Leeré más sobre esto! ¡Gracias de nuevo!

55
Si no comprende por qué sería útil una utilidad estándar para analizar las opciones de la línea de comandos, ¿tal vez no ha intentado escribir un analizador de shell para las opciones de la línea de comandos? Es una especie de dolor! Seguro que sería bueno si alguna otra herramienta hiciera esto por mí ... Además, tenga en cuenta: en 1980 no había Python, ni Ruby, ni Java, ni Perl, ni PHP, incluso C ++ aún no se había inventado, y el toda la idea de "shell scripting" todavía era bastante nueva. ¡Así que la idea de un analizador de línea de comandos estándar todavía era bastante novedosa!
wwoods
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.