我正在创建一个命令行解析器,并希望支持选项捆绑。但是,我不确定如何处理可能出现的歧义和冲突。考虑以下三种情况:
1
-I accepts a string
"-Iinclude" -> Would be parsed as "-I include"
2
-I accepts a string
-n accepts an integer
"-Iincluden10" -> Would be parsed as "-I include -n 10" because the 'cluden10' after the first occurrence of 'n' cannot be parsed as an integer.
3
-I accepts a string
-n accepts an integer
-c accepts a string
"-Iin10clude" -> ??? What now ???
如何处理最后一个字符串?有多种方法可以解析它,所以我只是抛出一个错误来通知用户有关歧义的信息,还是我选择解析产生最多的字符串,即“-I i -n 10 -c lude”?
我在网上找不到任何详细的约定,但就个人而言,我将此标记为歧义错误。
答案 0 :(得分:2)
据我所知,命令行参数解析没有标准,甚至没有跨平台的共识。因此,我们所能做的最好的事情就是吸引常识和principle of least astonishment。
Posix标准建议使用guidelines来解析命令行参数。它们只是指导方针;如链接部分所示,某些标准shell实用程序不符合。虽然Gnu实用程序预计符合Posix指南,但它们通常也会在某些方面有所偏差,包括使用“长”参数。
无论如何,Posix所说的关于分组的内容是:
在一个' - '分隔符后面分组时,应该接受一个或多个没有选项参数的选项,后面跟最多一个带选项参数的选项。
请注意,Posix选项都是单字符选项。另请注意,指南很明确,只允许选项组中的最后一个选项作为可接受参数的选项。
关于Gnu风格的长选项,除了getopt_long
实用程序的行为之外,我不知道标准。此实用程序为单个字符选项实现Posix样式,包括上面提到的分组选项语法;它允许单个字符选项,它将参数紧跟在参数之后,或者在一个(可能是单数的)选项组的末尾,参数作为下一个单词。
对于长选项,无论选项是否接受参数,都不允许分组。如果该选项接受参数,则允许两种样式:该选项后面紧跟=
,然后是参数,或者参数是后面的单词。
在Gnu样式中,长选项不能与单字符选项混淆,因为必须使用两个破折号(--
)指定长选项。
相比之下,许多基于TCL / Tk的实用程序(以及一些其他命令行解析器)允许使用单个-
的长选项,但不允许选项分组。
在所有这些样式中,选项分为两个不相交的集合:带参数的集合和不带参数的集合。
这些系统中没有一个是模棱两可的,尽管你似乎在提议的随机混合风格。即使使用正式的消歧规则,模糊也是危险的,特别是在命令行可能不可逆的控制台应用程序中。此外,如果将来扩展可用选项集,上下文消歧可以(甚至默默地)改变意义,这将是脚本中难以预测的错误的来源。
因此,我建议坚持使用简单的现有做法,例如Gnu,并且不要太费力地解释不符合的错误命令行。