如何防止最后一个参数需要用clap引用?

问题描述 投票:1回答:1

我正在使用clap并且在尝试解析参数时遇到意外行为。

我的命令行工具应该像这样工作

foo -u <user> <command>

e.g:

foo -u jack echo s
foo -u paul ls -al

我需要获得诸如用户之类的选项,但<command>本身,我需要成为其余的args。

下面的代码会导致我无法获得<command>值的行为,除非它被引用:

foo -u jack echo s
error: Found argument 's' which wasn't expected, or isn't valid in this context

虽然这很好用:

foo -u jack 'echo s'

有没有办法避免报价?

let matches = App::new("foo")
    .version("0.1")
    .arg(
        Arg::with_name("user")
            .short("u")
            .long("user")
            .required(true)
            .takes_value(true),
    )
    .arg(
        Arg::with_name("command")
            .help("The command to run")
            .required(true)
            .takes_value(true),
    )
    .get_matches();

我也开了一个issue on the clap repository

rust clap
1个回答
4
投票

默认情况下,clap只会解析任何参数一次。这意味着在-u jack echo s中,它将-u jack解析为“用户”选项,echo作为“命令”参数,并且有一个参数s,它不知道该怎么做(因此它“不是预期的”) 。

我假设你想要所有非选项参数而不只是一个,在这种情况下,在你的非选项参数(“命令”)上设置.multiple(true)就是你想要的。在这种情况下,它会将所有剩余的非选项参数解析为“命令”,并为每个参数提供一个列表(您可以随意处理):

let matches = App::new("foo")
    .version("0.1")
    .arg(
        Arg::with_name("user")
            .short("u")
            .long("user")
            .required(true)
            .takes_value(true),
    )
    .arg(
        Arg::with_name("command")
            .help("The command to run")
            .required(true)
            .takes_value(true)
            .multiple(true),
    )
    // parse as if program ran as:   foo -u jack echo s
    .get_matches_from(&["foo", "-u", "jack", "echo", "s"]);

// get command arguments
let command: Vec<&str> = matches.values_of("command").unwrap().collect();
println!("{:?}", command); // ["echo", "s"]

Playground link

© www.soinside.com 2019 - 2024. All rights reserved.