单字符的单破折号`-`,单词的双破折号`--`?


51

字母中使用单破折号和单词使用双破折号的惯例从何而来?为什么继续使用?

例如,如果输入ls --help,您将看到:

  -a, --all                  do not ignore entries starting with .
  -A, --almost-all           do not list implied . and ..
      --author               with -l, print the author of each file
  -b, --escape               print octal escapes for nongraphic characters
      --block-size=SIZE      use SIZE-byte blocks
  -B, --ignore-backups       do not list implied entries ending with ~
...

- and -- convention什至尝试使用谷歌搜索,但收效甚微。


6
这里只是挑剔,但从-技术上讲,该字符称为连字符。在大多数情况下,我们使用“破折号”一词指代破折号(-),有时也指代破折号(-),但都不是连字符(-)。
chharvey

4
但是,当著名的程序没有遵循约定时,这真的使我感到烦恼:java -version
Kimberly W

4
@Jamil是的。我在这里结束了疑惑,为什么是find . -delete
克日什托夫·文德

这样做的想法是为了使您可以编写诸如-ab激活a和的内容b。没有双破折号,-help会激活hel,和p选项。
亚伦弗兰克

Answers:


61

Unix编程艺术埃里克·雷蒙德史蒂芬说明这种做法如何演变:

在原始的Unix传统中,命令行选项是单个字母,后跟一个连字符。原始的Unix风格是在慢速的ASR-33电传打字机上发展起来的,它使简洁成为一种优点。因此是单字母选项。按住Shift键需要实际的努力;因此,偏好使用小写字母,并使用“-”(而不是更合乎逻辑的“ +”)启用选项。

GNU样式使用选项关键字(而不是关键字字母)加上两个连字符。几年后,当某些相当复杂的GNU实用程序开始用完单字母选项键时,它就演变了(这是症状的补丁,而不是潜在疾病的治愈方法)。它之所以受欢迎,是因为GNU选项比旧样式的字母汤更易于阅读。1个

[1] http://www.faqs.org/docs/artu/ch10s05.html


请注意,getopt()于1985年首次发布,但是UNOS(最古老的UNIX克隆)已于1982年(它写于1980年)发布了getargs(),并且getargs()支持short选项和单破折号long选项(Multics样式)。UNOS大量使用单点划线选项,UNOS由AT&T的前雇员编写。1988年,即使UNOS确认单破折号长选项效果很好,GNU也推出了双破折号长选项。
schily

28

为继续使用单字母选项的一个原因是因为他们可以串成:ls -ltr是一个很多更容易比输入ls --sort=time --reverse --format=long。很多时候两者都很好用。至于搜索此主题,请尝试“ unix命令行选项约定”。


1
+1谢谢,这确实对实施背后的逻辑有所帮助。
拉里

由于UNIX ls无法理解,ls --sort=time --reverse --format=long因此提起这种非标准方法也不是一个好主意。
schily

6

雷蒙德-报价由@jasonwryan有一些有用的信息,但在故事的中间开始:

  • 请记住,Unix最初是Multics的缩小范围版本,并且在其整个历史中,Unix中的功能通常是对在其他系统上看到和使用的功能的模仿或改编。
  • '-'选项字符是在Multics的使用。Bitsavers有其用户命令手册。
  • 其他系统使用不同的字符,其中一些声称具有更高的击键效率(例如'/'用于TOPS和VMS),而另外一些则较少(例如'('在VM / SP CMS中使用)。
  • Multics 选项是多字符的,例如,关键字之间用下划线分隔。
  • 较长的Multics选项通常具有较短的缩写形式,例如-printvs -pr(第3-8页)。
  • Unix选项是单字符的,并且在几年getopt后被引入。因为它不是原始Unix的一部分,所以有一些实用程序没有使用getopt,而是按原样保留。但是getopt帮助使程序保持一致。

另一方面,使用Unix的选项getopt是单字符。其他系统,尤其是所有较大的系统,都使用了关键字。有些(不是全部)允许将这些关键字缩写,即,只要选项没有歧义,就不会提供所有字符。该测试存在歧义性。例如:

  • 1985年初,我正在开发一个必须移植到PrimOS的程序。Prime的开发人员通过提供(尝试)模仿其他每个公司的命令语言,并从每个公司提供最常用的命令来与其他几家公司竞争。当然,他们支持缩写(VMS也是如此)。阅读在线帮助后,我打了sta一下电话,想得到status。那是的缩写start,命令解释器没有让我开始,而是注销了我。
  • X Toolkit(由xterm使用)允许使用缩写的选项。为了在xterm中有效地使用它,它必须对命令参数进行预处理,以便-v(对于版本)优先于-vb(可视铃声)。如果存在歧义,X Toolkit无法直接指定首选选项。

由于存在这种含糊不清的可能性,因此一些开发人员倾向于不允许使用缩写。 例如,Lynx使用多字符选项,但不允许使用缩写。

并非所有程序都使用过getopttar并且ps没有。您也不会注意到rcs(或sccs),您可以注意到破折号在哪里是可选的,而选项值是可选的。

考虑到所有这些,GNU开发人员通过扩展getopt以提供每个短选项的长版本,来适应其他系统中使用的关键字选项。例如,textutils 1.0 changelog说

Tue May  8 03:41:42 1990  David J. MacKenzie  (djm at abyss)

        * tac.c: Use regular expressions as the record boundaries.
        Give better error messages.
        Reformat code and make it more readable.
        (main): Use getopt_long to parse options.

fileutils中的更改较早:

Tue Oct 31 02:03:32 1989  David J. MacKenzie  (djm at spiff)

        * ls.c (decode_switches): Add long options, using getopt_long
        instead of getopt.

并且有人可能会发现更早的日期,但是文件头似乎显示了最早的日期:

/* Getopt for GNU.
   Copyright (C) 1987, 1989 Free Software Foundation, Inc.

(例如)与X Toolkit(1987)并发。您熟悉的大多数Unix实用程序(例如lsps)都使用了现有的单字符选项,这些选项需要定期访问本手册。在介绍时getopt_long,GNU开发人员并未通过首先添加新选项来做到这一点。他们首先列出了现有选项并提供了匹配的长选项。

因为它们是添加到现有曲目中,所以(再次)存在与现有选项冲突的问题。为避免这种情况,他们更改了语法,在长选项前使用两个破折号。

这些程序getopt_long由于通常的原因而继续以这种方式使用:

  • 脚本取决于选项;开发人员并不急于破坏脚本
  • 有书面的编码标准(可能有效)
  • 没有人提出一套明显不兼容的竞争性工具(BSD和GNU开发人员都互相复制选项名称)

3

在Wikipedia 命令行界面中报告:

在类Unix系统中,ASCII连字符减号通常用于指定选项。该字符通常后跟一个或多个字母。一个单独的连字符减号(不带任何字母)的参数通常指定程序应处理来自标准输入的数据或将数据发送到标准输出。在某些程序上,使用两个连字符-减号(-)指定“长选项”,其中使用了更具描述性的选项名称。这是GNU软件的常见功能。


这没有回答约定来自何处以及为什么继续使用约定的问题。
chharvey

1

我的猜测是,需要更多的描述性选项,并且对于更长的选项,您将不必担心用完单个字符选项。

一旦决定要多头期权,那么至少在计划同时支持多头和空头期权的情况下,您就会遇到问题。我不是很肯定,但是我相信arcege的答案对于-和-为什么是关键。通用处理例程,例如 getopt_long(),将需要知道单个命令行参数是否可以包含多个选项,例如。-ltr。因此,处理例程将需要能够在两者之间进行区分。如果我读了一个破折号-,那么命令行参数的其余部分可以匹配多个选项。如果我读双破折号-,则命令行参数的其余部分必须与单个选项匹配。

我最近才使用getopt_long(),由于它们更容易记住和自我记录,我开始喜欢长选项。如果我有以下两个命令:

./aggregator -f 15

./aggregator --flush-time 15

我会说使用长选项的第二个选项更能说明问题。


0

使用这两种方法可能有几个原因。其中之一当然是传统。程序员和用户都是人类,人类期望事物以某种方式起作用。如果没有理由进行更改(实际上,对于命令行而言,没有太多更改的理由),则不要更改。

话虽这么说,我知道有很多工具可以将单个连字符用作长选项,甚至完全摆脱连字符。这些工具起初可能很困难,并且在其他方​​面统一的系统中往往会像疣一样突出。

当我了解两者之间的区别(并且在成为第二本性之前)时,我总是会记住“短”连字符与“短”选项匹配,而“长”(或双)连字符与“长”匹配选项。我不知道这种推理是否用于双连字符样式的开发中,但这是可能的。

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.