简体   繁体   English

Rust:使用 Clap 解析用户输入字符串以进行命令行编程

[英]Rust: Parse user input String with clap for command line programming

I'd like to create a command line that utilizes clap to parse input.我想创建一个利用 clap 解析输入的命令行。 The best I can come up with is a loop that asks the user for input, breaks it up with a regex and builds a Vec which it somehow passes to我能想到的最好的方法是一个循环,它要求用户输入,用正则表达式分解它并构建一个 Vec 以某种方式传递给

loop {
    // Print command prompt and get command
    print!("> "); io::stdout().flush().expect("Couldn't flush stdout");

    let mut input = String::new(); // Take user input (to be parsed as clap args)
    io::stdin().read_line(&mut input).expect("Error reading input.");
    let args = WORD.captures_iter(&input)
           .map(|cap| cap.get(1).or(cap.get(2)).unwrap().as_str())
           .collect::<Vec<&str>>();

    let matches = App::new("MyApp")
        // ... Process Clap args/subcommands
    .get_matches(args); //match arguments from CLI args variable
}

Basically, I'm wondering if there is a way to direct Clap to use a pre-given list of arguments?基本上,我想知道是否有办法让 Clap 使用预先给定的 arguments 列表?

As @mcarton says, command line programs are passed their arguments as an array, rather than a string.正如@mcarton 所说,命令行程序将其 arguments 作为数组而不是字符串传递。 The shell splits the original command line (taking into account quotes, variable expansion, etc). shell 拆分了原始命令行(考虑到引号、变量扩展等)。

If your requirements are simple, you could simply split your string on whitespace and pass that to Clap.如果您的要求很简单,您可以简单地将字符串拆分为空格并将其传递给 Clap。 Or, if you want to respect quoted strings, you could use shellwords to parse it:或者,如果你想尊重带引号的字符串,你可以使用shellwords来解析它:

let words = shellwords::split(input)?;
let matches = App::new("MyApp")
    // ... command line argument options
    .get_matches_from(words);

This is how I ended up making the whole thing work:这就是我最终使整个工作正常进行的方式:

First, I put my whole main function in a loop so that it'd be able to get commands and, well, stay in the CLI.首先,我将整个主 function 放在一个loop中,以便它能够获取命令,并且,留在 CLI 中。

Next, I got input via stdin and split up the arguments接下来,我通过标准输入获得输入并拆分stdin

// Print command prompt and get command
print!("> ");
io::stdout().flush().expect("Couldn't flush stdout");
let mut input = String::new();
io::stdin().read_line(&mut input).expect("Error reading input.");
let args = WORD.captures_iter(&input)
           .map(|cap| cap.get(1).or(cap.get(2)).unwrap().as_str())
           .collect::<Vec<&str>>();

I then used Clap to parse, sorta like how @harmic suggested然后我使用 Clap 进行解析,有点像@harmic 建议的方式

let matches = App::new("MyApp")
    // ... command line argument options
    .get_matches_from(words);

and used subcommands instead of arguments .并使用subcommands代替arguments

eg.例如。

.subcommand(SubCommand::with_name("list")
    .help("Print namespaces currently tracked in the database."))

The whole file is here for the curious.整个文件都在这里为好奇。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM