2

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

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

foo -u <user> <command>

例如:

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

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

下面的代码会导致我无法获得值的行为,<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();

我还在clap 存储库上打开了一个问题

4

1 回答 1

5

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

要检索所有尾随参数,您需要.multiple(true)在最后一个参数(在您的情况下为“命令”)上设置,以便它解析所有剩余的参数。另外在 clap 命令上设置以下选项,以避免将剩余参数解析为 clap 参数:

这是一个例子:

let matches = App::new("foo")
    .version("0.1")
    .setting(clap::AppSettings::TrailingVarArg)
    .setting(clap::AppSettings::AllowLeadingHyphen)
    .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 paul ls -al
    .get_matches_from(&["foo", "-u", "paul", "ls", "-al"]);

let command: Vec<&str> = matches.values_of("command").unwrap().collect();
println!("{:?}", command); // ["ls", "-al"]

游乐场链接

于 2019-03-25T20:27:14.723 回答