【问题标题】:Define an option that has both a mandatory and optional argument定义一个同时具有强制参数和可选参数的选项
【发布时间】:2019-08-30 05:02:50
【问题描述】:

我目前正在尝试提出一种构建命令行选项的方法,该选项在提供时可以采用一个必需参数或第二个可选参数(除了必需的参数)。我正在尝试使用 apache commons cli 来实现这一点。

即myProgram -a [整数]

myProgram -a "test" --> isValid
myProgram -a "test" 2 --> also isValid

我尝试过: Option.builder("a").hasArg().numberOfArgs(2).optionalArg(true).build();

&

Option.builder("a").hasArg().numberOfArgs(2).build();

两者都没有按预期工作。第一个示例使两个参数都是可选的,并且允许传递违反要求的空参数。

第二个示例使两个参数都需要,并且在仅提供字符串类型 arg 时失败。

我查看了 commons cli 的文档,但他们提供的用例并没有涉及到像这样的复杂案例,同样没有从 api 文档中获得太多细节。

我希望程序在 -a 未提供任何值时会失败,但在提供 1 或 2 个参数时会成功,如前所示。

【问题讨论】:

    标签: java command-line-arguments apache-commons-cli


    【解决方案1】:

    根据我对 appache-commons-cli 文档的理解(我可能错了),似乎没有办法在每个参数的基础上设置“optionalArg”。

    我在示例中看到它的使用方式也是如此,它似乎接受了带有分隔符的参数,例如 -D<property>=<value> 而不是空格?不过我不确定。

    但是,是的,对于你想要的,你可以把它弄脏并允许可选参数,然后在选项没有所需参数时拒绝它(我知道违背了使用 commons-cli 的目的)。

    编辑:您尝试过使用PatternOptionBuilder 吗?这个例子让我很感兴趣:

    例如,以下允许命令行标志 '-v -p 字符串值 -f /dir/file'。感叹号在必填项之前 选项。

     Options options = PatternOptionBuilder.parsePattern("vp:!f/");
    

    它说感叹号可以在强制选项之前使用,但我不确定它是否可以与强制参数一起使用?不过我没试过。

    【讨论】:

    • Dirty 是我现在正在尝试的,但到目前为止还不是很漂亮,呵呵,我认为带分隔符的方法也违反了我正在编写的应用程序的要求。
    • 我查看了 PatternOptionBuilder。似乎更适合指定命令行参数应该是什么(和顺序),而不是让我指定比标准选项值更复杂的组合。我走了很长一段路,按照建议做了。将这两个参数设为可选,然后检查它们是否存在并采取相应措施。感谢您的额外目光,我很感激。
    • 不客气。如果您不介意接受该回复,如果它对您真的有用的话。
    • 如果你走这条路,请注意参数的长描述是可设置的。所以仍然可以在帮助中描述回给用户。
    【解决方案2】:

    过去,在这些情况下,我添加了第二个选项。所以在你的例子中,-b。

    -b [bvalue]   If -a is enabled, ensure that it uses bvalue to thinginate.
    

    如果您的第二个(可选)值充当标志,则它可以只是一个布尔标志。

    如果您的第二个(可选)值是更多任意输入,则第二个选项可以采用单个必需参数。

    虽然我确信你有理由将你的论点组织为 -a reqdval optval,但它通常会导致更有用的命令行无论如何都没有这些多层可选性(即在选项)。您可以将其视为两级和三级嵌套菜单之间的用户体验差异。由于项目数量有限,两级菜单通常更有用。 (如果没有更具体的用例细节,答案必须笼统。)

    【讨论】:

      【解决方案3】:

      所以你有一个选项可以提供零次或一次,并且可以有一个或两个值?

      final Options options = new Options()
                  .addOption(Option.builder("a").hasArg().hasArgs().build());
      CommandLine cmd = new DefaultParser().parse(options, args);
      LOG.debug(Arrays.asList(args).toString() + " : " + Arrays.asList(cmd.getOptionValues("a")).toString());
      
      DEBUG :: [-a, b] : [b]
      DEBUG :: [-a, b, c] : [b, c]
      

      当提供的参数太多或太少时,您可能希望引发自己的解析异常。

      如果您想多次提供-a,请查看此答案:https://stackoverflow.com/a/64611857/8656281

      【讨论】:

        猜你喜欢
        • 2020-03-16
        • 2014-04-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多