如何允许 getopt 和 get_long_opt 也处理任意参数而不发出错误?

How to allow getopt and get_long_opt to handle arbitrary arguments too without emitting error?

我正在编写一个程序 A,它依次调用任意程序 B。 调用A时,有些参数是A需要的,有些参数应该重定向到B,但A不知道。

我怎样才能让 A 收集那些传递给它的参数,但是无法识别 , 进字典也许。到目前为止,我每次使用:

getopt_long_only(argc, argv, "...

getopt(argc, argv, "...

我收到 "unrecognized option" 或 "illegal option" 的错误。而那些确实是A无法识别的,但我希望A忽略它,你认为这可行吗?

一般来说,这个问题非常棘手,甚至棘手,除非您为如何使用您的程序设置一些基本规则。

您可以在调用选项解析器之前通过设置 opterr = 0; 来抑制自动消息。不幸的是,这是简单的部分。

假设给你一个命令行:

wrapper_program -baxt cantaloupe -d designator

此外,假设 -b-d 都不是包装程序的选项。现在的困难在于确定 -b 选项是否接受参数(在这种情况下,参数是 axt)。如果 -b 不带参数,还有以 -a 开头的额外选项 — 但它是否带参数(即 xt)或者 x 也是一个选项?如果 x 是一个选项,那么它是否接受一个参数(这将是 t)或者 t 也是一个选项 - 并且它是否接受一个参数(这将是 cantaloupe).如果第一个参数 -baxt 有一个附加参数的选项,那么您是希望 cantaloupe 选项结束参数解析,还是代码应该进行 GNU 风格的参数排列?如果它应该进行参数置换,-d 选项是否采用参数 (designator) 还是非选项参数?

您可以设置基本规则来解决此类问题,但您必须认真思考并仔细编写代码 — 并进行彻底测试。如果您知道包装的程序采用长参数还是短参数,可能会更容易。

您可能会发现要求包装程序的选项在双破折号之后更好:

wrapper_program -w wrapper-argument -- -b=axt -d designator cantaloupe

这个想法是包装程序的参数在 -- 之前,包装程序的参数在它之后。这在两组参数之间提供了干净、清晰的分离。

另一种方法是使用 'pass-through' 选项(C 编译器通常使用 -Wl,-arg-for-linker 等符号来支持此选项)。例如,-p 选项可能带有一个参数,该参数将逐字传递给包装程序:

wrapper_program -w wrapper-argument -p -b=axt -p -d -p designator cantaloupe

-p 选项指定应将以下参数传递给包装程序。

使用 -b=axt 表示法意味着使用 getopt_long() 而不是 getopt(),但如果 -b 接受参数,则 =axt 选项将是getopt() 被视为参数,而据我所知,getopt_long() 会将 axt 视为参数。

对此类设计要谨慎。它们既不容易编写也不一定易于使用。