Как я могу предотвратить цитирование последнего аргумента с хлопком? - PullRequest
1 голос
/ 25 марта 2019

Я использую хлопок, и я получаю неожиданное поведение при попытке разобрать аргументы.

Мой инструмент командной строки должен работать следующим образом

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();

Я также открыл проблему в хранилище хлопков .

1 Ответ

4 голосов
/ 25 марта 2019

По умолчанию clap анализирует любой аргумент только один раз. Это означает, что в -u jack echo s он будет анализировать -u jack как параметр "user", echo как аргумент "command" и иметь аргумент 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"]

Ссылка на игровую площадку

...