何时以及如何在Unix / Linux中引入双破折号(-)作为选项定界符的结尾?


49

我不认为历史 Unix中的shell /实用程序或4.4BSD之类的 “最新”东西都不支持使用双破折号(或两个连续的连字符)作为选项定界符结尾。使用FreeBSD,您可以看到例如在2.2.1发行版(1997)的rm 手册页中引入的注释。但这只是一个命令的文档。

查看我能找到的最旧的GNU fileutils 更改日志,我看到此1(稍作更改):

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.

这早于Linux。显然要考虑到以下事实:您可能想要创建一个文件名,该文件名包含与时间规范相同的位数(八位或十位十进制数字),而不是为现有文件指定时间戳。


  • posix.1是不是在Unix shell中引入了双破折号(--)作为选项定界符结尾
  • 这是不是因为某些人想在touch90年代初期使用文件名中的数字,然后才以零碎的方式一次使用一个实用程序十年而开始了?
  • 变更日志中关于什么的热烈评论是什么?
  • POSIX Utility语法何时引入了准则10参数–应该作为表示选项结束的定界符。[...])?

1.与相反,即在全局范围内记录所有命令用法中的长选项,这是无关的。在另一方面,你可以看到参考定界符出现在像GNU rm.c于2000年作为一个评论,之前被暴露给最终用户在2005年(该diagnose_leading_hyphen功能)。但这一切都在以后,并且涉及一个非常特定的用例。


1
BSD4.3RENO至少有一个getopt支持的--
斯特凡Chazelas

@StéphaneChazelas您还评论getopt不是唯一能够处理定界符的api。这是否意味着在实际使用之前就已经提供了该功能并使其正常工作?恐怕这超出了我。谢谢!

2
它可能是由几个随机程序临时使用的,但是我认为它getopt是在1980年代初编写时首次被记录的。如果有人可以从Uniforum '85获得getopt论文,那可能会提供一些历史。
Mark Plotnick

2
@MarkPlotnick,实际上是SysIII(1980)上的getopt支持--
斯特凡Chazelas

Answers:


38

据我所知,使用--的结束选项-标记开头sh,并getopt在系统III UNIX(1980)。

根据Bourne Shell家族的历史,Bourne Shell 首次出现在Unix 7版(1979年)中。但它没有一种方式set,以从分隔参数选项。因此原始的Bourne外壳可以做到:

  • set -e -打开错误退出模式
  • set arg1 arg2 ...-设置位置参数$1=arg1$2=arg2等等。

但是:set arg1 -e arg2会给您$1=arg1$2=arg2然后打开错误退出。哎呀

System III Unix(1980)修复了该错误,并进行了介绍getopt。根据getopt手册页

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.

据我所知,这是它出现的第一位

从那里开始,似乎其他命令都采用了--约定来解决参数解析歧义的问题(例如上面touchrm您在上面引用的示例)在整个1980年代疯狂,无标准的日子。

其中一些零星采用的方法已在POSIX.1(1988)中进行了编纂,这是关于“ POSIX必需的合并”的变更日志注释的来源。

但是直到POSIX.2(1992)才采用实用程序语法准则,其中包含著名的准则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.

这就是从“ being脚”到普遍推荐的地步。


感谢您抽出宝贵的时间!在我的“研究”中,我大多忽略了getopt,因为我不明白为什么需要这种抽象的实用程序/函数。现在我读到它在某些时候被重新使用(getopts)来处理空格等,而sysv getopt无法做到。我将了解更多信息!再次感谢!

5
如果您不明白为什么解析命令行选项的标准实用程序会很有用,那么也许您还没有尝试为命令行选项编写Shell解析器?有点痛苦!当然,如果有其他工具为我做这件事会很好。。。还要记住:在1980年,还没有Python,Ruby,Java,Perl,PHP-甚至还没有C ++的发明, “ shell脚本”的整个想法仍然很新。因此,标准命令行解析器的想法仍然很新颖!
wwoods 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.