Quand et comment le double tiret (-) a-t-il été introduit comme séparateur de fin d’options sous Unix / Linux?

49

Je ne pense pas que le shell / les utilitaires dans Unix historique, ni dans quelque chose d'aussi "récent" que 4.4BSD, prennent en charge l'utilisation d'un double tiret (ou de deux tirets consécutifs) comme délimiteur de fin d'options . Avec FreeBSD , vous pouvez voir par exemple une note introduite dans les rm pages de manuel avec la version 2.2.1 (1997). Mais ceci est juste la documentation pour une commande.

En regardant le plus ancien changelog GNU fileutils que je puisse trouver, je vois ceci 1 (légèrement modifié):

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.

Ceci est antérieur à Linux . Il est clair que vous voudrez peut-être créer un fichier avec un nom contenant le même nombre de chiffres qu'une spécification temporelle (nombre décimal à huit ou dix chiffres), plutôt que de spécifier un horodatage pour un fichier existant ...


  • C'est donc posix.1 qui a introduit le double tiret ( --) comme délimiteur de fin d’options dans les shells Unix?
  • Est-ce que tout cela a commencé parce que certaines personnes voulaient utiliser des chiffres dans les noms de fichiers touchau début des années 90 et ensuite cela s'est poursuivi de manière fragmentée, un utilitaire à la fois pendant une décennie ??
  • Quel est le commentaire animé dans le journal des modifications?
  • Quand la directive 10 ( L'argument - devrait être acceptée comme un délimiteur indiquant la fin des options. [...] ) a été introduite dans la syntaxe POSIX Utility ?

1. Par opposition à cela, c’est- à - dire la documentation des options longues dans l’utilisation globale des commandes, ce qui n’est pas lié. D'autre part, vous pouvez voir que la référence au délimiteur apparaît dans GNU rm.c en 2000 sous forme de commentaire, avant d'être exposée à l'utilisateur final en 2005 ( fonction diagnose_leading_hyphen ). Mais tout cela est beaucoup plus tard et concerne un cas d'utilisation très spécifique.

Gilles, arrête de faire le mal
la source
1
BSD4.3RENO avait au moins une getoptprise en charge --.
Stéphane Chazelas
@ StéphaneChazelas Vous avez également fait un commentaire au sujet getopt ne pas être le seul api en mesure de traiter le delimiter. Cela signifie-t-il que cela avait été prévu et travaillé avant son utilisation effective? J'ai bien peur que cela me dépasse. Je vous remercie!
2
Il a probablement été utilisé ponctuellement par plusieurs programmes aléatoires, mais je pense qu’il a été documenté pour la première fois lors de getoptsa rédaction au début des années 80. Si quelqu'un peut obtenir le document getopt d'Uniforum '85, cela pourrait donner un peu d'histoire.
Mark Plotnick
2
@ MarkPlotnick, en fait, le getopt tel que trouvé sur le support SysIII (1980) --.
Stéphane Chazelas

Réponses:

38

Autant que je sache, l’utilisation de --marqueur de fin d’options commence par shet getoptdans System III Unix (1980).

Selon cette histoire de la famille Bourne Shell , le Bourne Shell est apparu pour la première fois dans la version 7 Unix (1979). Mais il n'y avait pas moyen setde séparer les options des arguments . Donc, le shell Bourne original pourrait faire:

  • set -e - activer le mode de sortie sur erreur
  • set arg1 arg2 ...- définit les paramètres de position $1=arg1, $2=arg2etc.

Mais: set arg1 -e arg2vous donnerait $1=arg1, $2=arg2et tourner à la sortie sur erreur . Oups.

System III Unix (1980) a corrigé ce bogue et l'a introduit getopt. Selon getoptla page de manuel 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.

Autant que je sache, c'est le premier endroit où il apparaît.

À partir de là, il semble que d’autres commandes aient adopté la --convention pour résoudre les arguments en analysant les ambiguïtés (telles que les exemples avec touchet que rmvous citez ci-dessus) tout au long de la folle journée des années 1980.

Certaines de ces adoptions au coup par coup ont été codifiées dans POSIX.1 (1988), d'où provient le commentaire du journal des modifications concernant le "kludge requis par POSIX".

Mais ce n’est que jusqu’à POSIX.2 (1992) que les Lignes directrices concernant la syntaxe utilitaire ont été adoptées. Elles contiennent la célèbre ligne directrice 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.

Et c’est ce qui est passé d’un simple "kludge" à une recommandation universelle.

Wwoods
la source
Je vous remercie d'avoir pris le temps! J'avais surtout ignoré getopt dans mes "recherches" car je ne comprenais pas pourquoi ce type d'utilitaire / fonction abstraite était requis. Maintenant, j'ai lu que cela avait été réorganisé (getopts) à un moment donné pour traiter les blancs, etc. comme sysv getoptne le pouvait pas. Je vais en lire plus à ce sujet! Merci encore!
5
Si vous ne comprenez pas pourquoi un utilitaire standard d'analyse des options de ligne de commande serait utile, vous n'avez peut-être pas essayé d'écrire un analyseur de shell pour les options de ligne de commande? C'est un peu pénible! Ce serait bien si un autre outil me permettait de le faire ... N'oubliez pas: en 1980, il n'y avait pas de Python, pas de Ruby, pas de Java, pas de Perl, pas de PHP - même le C ++ n'avait pas encore été inventé, et toute l'idée de "shell scripting" était encore assez nouvelle. Donc, l’idée d’un analyseur en ligne de commande standard était encore novatrice!
Wwoods