首页 > 编程语言 >Rust命令行解析程序:Clap

Rust命令行解析程序:Clap

时间:2023-10-12 11:33:35浏览次数:37  
标签:exe name get matches -- Clap 命令行 arg Rust

Rust命令行解析程序:Clap

基于Clap 4.4.6

参考资料:Clap官方手册

Chapter 1

配置解析器

使用Command结构体的new方法构建解析器:

// arg.exe
use clap::{arg, Command};

fn main() {
    // 只要调用clap解析命令行参数,--help和--version会自动添加到命令行参数列表中
    // 使用arg!宏定义了两个命令行参数:two, one
    let matches = Command::new("MyApp")
        .version("1.0")
        .author("Kevin K. <[email protected]>")
        .about("Does awesome things")
        .arg(arg!(--two <VALUE>).required(true))
        .arg(arg!(--one <VALUE>).required(true))
        .get_matches();

    println!(
        "two: {:?}",
        matches.get_one::<String>("two").expect("required")
    );
    println!(
        "one: {:?}",
        matches.get_one::<String>("one").expect("required")
    );
}

用法:

  • arg.exe --two foo --one bar:两个参数分别对应foobar
  • arg.exe -harg.exe --help:输出帮助信息
  • arg.exe -varg.exe --version:输出版本号

使用command!宏构建解析器:

use clap::{arg, command};

fn main() {
    // 需要启用 `cargo` 这个feature,在Cargo.toml的clap依赖中添加;
    // requires `cargo` feature, reading name, version, author, and description from `Cargo.toml`
    let matches = command!()
        .arg(arg!(--two <VALUE>).required(true))
        .arg(arg!(--one <VALUE>).required(true))
        .get_matches();

    println!(
        "two: {:?}",
        matches.get_one::<String>("two").expect("required")
    );
    println!(
        "one: {:?}",
        matches.get_one::<String>("one").expect("required")
    );
}

使用Command::next_line_help方法把帮助信息中的参数描述挪到下一行打印,需要启用 cargofeature

use clap::{arg, command, ArgAction};

fn main() {
    let matches = command!() // requires `cargo` feature
        .next_line_help(true)
        .arg(arg!(--two <VALUE>).required(true).action(ArgAction::Set))
        .arg(arg!(--one <VALUE>).required(true).action(ArgAction::Set))
        .get_matches();

    println!(
        "two: {:?}",
        matches.get_one::<String>("two").expect("required")
    );
    println!(
        "one: {:?}",
        matches.get_one::<String>("one").expect("required")
    );
}

Chapter 2

Positionals

无需输入参数名称,直接输入参数内容,按位对应

// arg.exe
fn main() {
    let matches = command!() // requires `cargo` feature
        .arg(Arg::new("name"))
        .arg(Arg::new("age"))
        .get_matches();
	// get_one返回一个Option,如果用户有输入则解析出来,没有输入则是None
    println!("name: {:?}, age: {:?}", matches.get_one::<String>("name"), matches.get_one::<String>("age"));
}

用法:arg.exe zhangsan

输出:name: Some("zhangsan"), age: None

为一个参数传递多个内容,需要更改解析这个参数时的行为,相关方法为action(),其参数为枚举类型ArgAction

use clap::{command, Arg, ArgAction};

fn main() {
    let matches = command!() // requires `cargo` feature
        .arg(Arg::new("name").action(ArgAction::Append))
        .get_matches();

    let args = matches
        .get_many::<String>("name")
        .unwrap_or_default()
        .map(|v| v.as_str())
        .collect::<Vec<_>>();

    println!("names: {:?}", &args);
}

用法:arg.exe zhangsan lisi

输出:names: ["zhangsan", "lisi"]

Options

前面一小节传递参数无需指明参数的名称,直接传递内容;接下来为每个参数指定名称,这样在传递参数时更清晰,并且可以不按位置传递

use clap::{command, Arg, ArgAction};

fn main() {
    let matches = command!() // requires `cargo` feature
        .arg(Arg::new("name").short('n').long("name").action(ArgAction::Append)) // 定义新参数,id为name,传入可缩写为n,扩写为name, 是列表
        .arg(Arg::new("age").short('a').long("age")) // 定义新参数,id为age,缩写为a,扩写为age,是个Set(即只能传入一个)
        .get_matches();

    let args = matches
    .get_many::<String>("name")
    .unwrap_or_default()
    .map(|v| v.as_str())
    .collect::<Vec<_>>();

    println!("names: {:?}", &args);
    println!("age: {:?}", matches.get_one::<String>("age"));
}

当我们给参数定义缩写或者扩写时,如果要传递(因为并没有指明这是个必选参数)这个参数,传入时必须使用-n或者--name,其后接参数内容;另外,我们指明name参数接收的是个列表,所以如果给name传递多个参数,每次传递时都要使用-n或者--name,否则无法识别;另外,由于我们给参数指定了缩写或者扩写,因此可以无序传递

以下传递方式均合法:

arg.exe -n zhangsan -a 18 --name lisi -n wangwu

arg.exe -a 13 --name zhangsan -n lisi

arg.exe:由于两个参数均非必选,所以可以一个也不传递

以下传递方式非法:

arg.exe -a 18 -a 9:age参数为Set,只能传递一次

arg.exe zhangsan -a 2:没有使用-n或者--name

arg.exe zangsan lisi -a 8:同上

Flags

根据文档给的示例,把Flags理解为开关即可

use clap::{command, Arg, ArgAction};

fn main() {
    let matches = command!() // requires `cargo` feature
        .arg(
            Arg::new("verbose")
                .short('v')
                .long("verbose")
                .action(ArgAction::SetTrue),
        )
        .get_matches();

    println!("verbose: {:?}", matches.get_flag("verbose"));
}

将verbose的action设置为ArgAction::SetTrue,如果在参数中出现-v或者--verbose即为打开,否则默认为关闭;而ArgAction::SetFalse的行为相反。

use clap::{command, Arg, ArgAction};

fn main() {
    let matches = command!() // requires `cargo` feature
        .arg(
            Arg::new("verbose")
                .short('v')
                .long("verbose")
                .action(ArgAction::Count),
        )
        .get_matches();

    println!("verbose: {:?}", matches.get_count("verbose"));
}

将verbose的action设置为ArgAction::Count,即统计-v或者--verbose在参数中出现的次数

用法:arg.exe -vvv -v --verbose

输出:verbose: 5

Subcommand

子命令也是Command,通过Command::subcommand来添加;子命令可以有自己的版本号、帮助信息等,甚至可以有自己的子命令,即可以嵌套

use clap::{arg, command, Command};

fn main() {
    let matches = command!() // requires `cargo` feature
        .propagate_version(true)
        .subcommand_required(true)
        .arg_required_else_help(true)
        .subcommand(
            Command::new("add")
                .about("Adds files to myapp")
                .arg(arg!([NAME])),
        )
        .get_matches();

    match matches.subcommand() {
        Some(("add", sub_matches)) => println!(
            "'myapp add' was used, name is: {:?}",
            sub_matches.get_one::<String>("NAME")
        ),
        _ => unreachable!("Exhausted list of subcommands and subcommand_required prevents `None`"),
    }
}

添加子命令add,并且该子命令有一个参数,并且该子命令为必选,如果没有则显示帮助信息

用法:arg.exe add hello

输出:myapp add' was used, name is: Some("hello")

Defaults

use clap::{arg, command, value_parser};

fn main() {
    let matches = command!() // requires `cargo` feature
        .arg(
            arg!([PORT])
                .value_parser(value_parser!(u16))
                .default_value("2020"),
        )
        .get_matches();

    println!(
        "port: {:?}",
        matches
            .get_one::<u16>("PORT")
            .expect("default ensures there is always a value")
    );
}

默认选项。当用户没有传递该参数时,使用默认值

用法:arg.exe 443arg.exe

输出:port: 443port: 2020

标签:exe,name,get,matches,--,Clap,命令行,arg,Rust
From: https://www.cnblogs.com/ptrzs/p/17759112.html

相关文章

  • 14.2 Socket 反向远程命令行
    在本节,我们将继续深入探讨套接字通信技术,并介绍一种常见的用法,实现反向远程命令执行功能。对于安全从业者而言,经常需要在远程主机上执行命令并获取执行结果。本节将介绍如何利用_popen()函数来启动命令行进程,并将输出通过套接字发送回服务端,从而实现远程命令执行的功能。在实现......
  • 11. 用Rust手把手编写一个wmproxy(代理,内网穿透等), 实现健康检查
    11.用Rust手把手编写一个wmproxy(代理,内网穿透等),实现健康检查项目++wmproxy++gite:https://gitee.com/tickbh/wmproxygithub:https://github.com/tickbh/wmproxy健康检查的意义健康检查维持着系统的稳定运行,极大的加速着服务的响应时间,并保证服务器不会把消息包转......
  • 搭建 Kubernetes 集群 —— 命令行工具 kubectl
    命令行工具(kubectl)Kubernetes提供kubectl是使用KubernetesAPI与Kubernetes集群的控制面进行通信的命令行工具。这个工具叫做kubectl。一、在任意节点使用kubectl最开始只能在master节点上使用kubectl工具,比如kubectlgetnodes因为之前在部署master节点时......
  • rust HashMap 排序
    按照key和value升序、降序、自定义排序示例usestd::collections::HashMap;usestd::cmp::Ordering;fnmain(){letmutdf=HashMap::new();forxin5..=12{letk=format!("key_{}",x);letv=format!("value_{}",x);......
  • 实现一个自动生成小学四则运算题目的命令行程序
    作业所属课程https://edu.cnblogs.com/campus/gdgy/CSGrade21-12/homework/13016作业要求https://edu.cnblogs.com/campus/gdgy/CSGrade21-12/homework/13016作业目标实现一个自动生成小学四则运算题目的命令行程序结对项目艾山·依力哈木+3120005145一......
  • Linux命令行基本操作
    本例要求熟悉新装LINUX系统中命令行界面的获取方法,并通过命令行完成下列任务:pwd、cd、ls命令练习路径练习路径切换练习cat命令练习less命令练习hostname命令练习显示CPU与内存查看IP地址创建数据练习查看部分文件内容过滤文件内容vim文本编辑器关机与重启简单命令......
  • 【Postman】以命令行形式执行Postman脚本(使用newman)
    以命令行形式执行Postman脚本(使用Newman)目录以命令行形式执行Postman脚本(使用Newman)一、背景二、Newman的安装1、Node.js2、Newman三、脚本准备四、Newman的执行1、run2、变量的使用3、参数化文件4、指定folder五、生成报告1、生成简洁版html报告2、生成加强版html测试报告和Json......
  • sourcetree界面卡死,改用命令行提交
    在github上创建了空仓库https://github.com/wantnon/UE-Yang-426,并clone到了本地(C:/GitHub2/UE-Yang-426),然后把自己修改过的ue4.26源码拷贝到这个路径,用sourcetree提交,结果由于一次性添加文件太多,“暂存所有”这一步sourcetree界面卡死,所以只能考虑用命令行提交了,问gpt4:于是打......
  • Rust安装及学习资料
    目录官网包管理Rust程序设计语言通过例子学Rust在线运行安装rustup升级Rust卸载Rust创建项目官网https://www.rust-lang.org/zh-CN/包管理https://crates.io/Rust程序设计语言https://kaisery.github.io/trpl-zh-cn/通过例子学Rusthttps://rustwiki.org/zh-CN/......
  • Rust cargo常用命令
    目录设置国内镜像创建新项目构建项目运行项目检查项目,但不构建可执行文件运行项目的测试发布项目更新依赖查看项目依赖关系树创建新的库项目文档生成设置国内镜像cd~/.cargo#创建config文件vimconfig#添加如下镜像源[source.crates-io]registry="https://github.com/......