为什么控制台应用程序以以下任一方式获取参数:
a) one dash (myapp -arg1 123; ls -al)
b) two dashes (myapp --arg1 123; git push origin master --force)
c) without dashes at all (myapp 123; man ls)
d) without dashes but with the equal sign (myapp arg1=123; dd if=/dev/zero)
难道没有一个标准约定吗?即使在标准 Linux 应用程序中,a)、b) 和 d) 三种情况也确实同时存在。而且很难记住何时应该使用 -help 以及何时使用 --help。
答案1
破折号用于表示选项,它修改命令的行为。不带破折号的参数表示命令的主要参数,通常是文件名。
单连字符通常引入仅包含一个字母的选项。多个这样的选项可以组合在一起,因此ls -a -l
可以缩写为ls -al
。这是大多数早期 Unix 命令的标准约定。
双连字符引入整个单词的选项。这一约定对于将它们与上述分组区分开来是必要的。这种选项风格在 GNU 版本的实用程序中得到普及,因为它们通常具有太多的功能,以至于无法使用单个字母来助记。
有时一个选项需要它自己的参数。其风格各不相同:有些命令使用-o parameter
,有些命令使用-oparameter
,有些命令使用--option=parameter
,有些允许多种形式。
还有一些命令发明了自己独特的参数风格。这些通常是非常古老的命令,来自于参数约定达成共识之前。这方面的例子有tar
和dd
。也是不寻常的,因为它是一个在创建约定find
之前使用完整单词选项的旧命令;--
它的论点实际上是一种自己的语言,因为它的需求不符合典型的command -options parameters
范式。
命令之间存在差异的其他原因是 Unix 最初没有参数解析库函数。直到其生命周期很长一段时间内,getopt
和getopts
函数才被创建。使用这些库本质上会迫使您遵循常见做法。但较旧的程序会进行自己的临时参数解析,并且不同的程序员会做出不同的决定。
答案2
@Barmar 是正确的,但缺少一些信息。为什么会发生这种情况,完全是因为程序代码的编写方式,更具体地说,是用来解析参数的。
在详细讨论之前,我想澄清一些术语。首先,你所谓的“选项”实际上也是参数。事实上,您在命令行中输入的所有内容都是一个参数(包括程序的名称)。这些参数通常存储在一个数组中(argv
在 C 中称为)。然后,程序选择如何(或是否)解析这些参数并做出相应的行为。现在,参数通常采用以下三种形式之一:
- 标志(不接受参数;只需打开或关闭行为)
- 开关(接受参数;根据参数修改行为)
- 参数(纯数据并不意味着修改行为)
1
和2
通常被称为OPTIONS
和 ,旨在改变程序行为,但两者以不同的风格出现(正如 Barmar 也提到的)。 C 的getopt
库实际上在这方面提供了很大的灵活性。尽管约定是将选项指定为前面有一个连字符的单个字母或前面有两个连字符的完整单词,但用 编写的程序getopt
实际上允许以下任何一项等效(假设help
给出h
索引) ):
-h
,--h
,--help
然而,-help
实际上是不允许的getopt
(因此,如果一个工具使用-help
其使用标志,那么您可以非常确定它不是用getopt
库编写的)。这是因为getopt
将单个连字符解释为表示组合选项列表,因此它解释-help
为-h -e -l -p
。
此外,当选项采用参数(通常称为“optargs”)时,您可以通过几种方法来指定它们。以下 - 假设 的索引opt
是o
,这opt
需要一个 optarg1—也都是等价的:
-oParameter
,-o Parameter
,--opt=Parameter
,--opt Parameter
尽管该getopt
库现在是一个广泛使用的标准,但许多早于它的工具(例如tar
)仍然使用自己的解析设置,因此 Whytar -xjf
相当于tar xjf
.
长话短说:getopt
并不总是存在,因此程序员必须以自己的方式解析参数。但是,较新的工具通常会使用它,因此它们的行为是理智且可预测的。
1 有一种没有充分记录的能力,即选项能够接受 optarg 但不能要求一。可选的 optargs 会导致各种烦人的事情,并导致一些更常见的指定选项的方法无效(因为它们是不明确的)。幸运的是,采用可选参数的参数并不常见。
答案3
options 以破折号开头,通常是一个字母,可以指定多个选项
ls -l -h
or
ls -lh
options 以两个破折号开头,一般带单词,多个选项不行
ls --list --human