使用Rust开发命令行程序(下)(rust执行cmd命令)

使用Rust开发命令行程序(下)(rust执行cmd命令)

编码文章call10242025-01-22 14:57:4114A+A-

前言

Rust 的标准库虽然强大,但对于一些复杂功能来说,使用第三方库可以显著提高开发效率。在命令行程序开发中,clap 和 structopt 是两款广泛使用的库,它们能够帮助我们快速实现参数解析和命令管理。本章将详细介绍如何使用这两个库来构建强大的命令行程序。

引入第三方库

方式一

修改 Cargo.toml

在项目的 Cargo.toml 文件中添加依赖:

[package]
name = "command_line_demo"
version = "0.1.0"
edition = "2021"

[dependencies]
clap = { version = "4.5.23", features = ["derive"] }
structopt = "0.3.26"

通过 cargo build 下载并构建依赖库。

方式二

直接使用cargo add命令直接添加依赖,具体如下所示:

cargo add clap --features derive
cargo add structopt

使用clap

clap(Command Line Argument Parser)是 Rust 中最流行的命令行参数解析库之一,它提供了简单直观的 API 和丰富的功能。

基本用法

示例:解析简单的参数

use clap::{Arg, Command};

fn main() {
    let matchs = Command::new("My Cli App") // 创建一个Command结构体实例
        .version("0.1.0") // 版本信息
        .author("Alen") // 作者信息
        .about("Does awesome things") // 命令行简介
        .arg( // arg是一个宏,从字符串用法中创建Arg
            Arg::new("name") // 创建一个Arg实例,必须传入一个唯一的参数名称
                .short('n') // 参数短名称
                .long("name") // 参数m长名称
                .value_name("NAME") // 帮助消息/用法中参数值的占位符。
                .help("Sets a custom name") // 参数帮助信息
                .required(true) // 参数是否必须
        )
        .arg(
            Arg::new("debug")
                .short('d')
                .long("debug")
                .help("Sets a custom debug flag")
        )
        .get_matches(); // 解析env::args_os ,失败时退出。

    if let Some(name) = matchs.get_one::<String>("name") {
        println!("Hello {:?}", name);
    }
    // get_one: 获取特定选项或位置参数的值。
    // 即在运行时获取附加值的参数。如果使用了错误的类型,则返回错误。
    // 如果该选项不存在,则返回None 。

    if let Some(debug) = matchs.get_one::<String>("debug") {
        println!("Debug: {:?}", debug);
    }

}

运行结果如下所示:

  command_line_demo git:(master)  cargo run -- --name alen --debug true
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.08s
     Running `target/debug/command_line_demo --name alen --debug true`
Hello "alen"
Debug: "true"

使用 derive 特性

clap 提供了 derive 宏,可以用结构体定义命令行参数,更加简洁。

示例:

use clap::Parser;

#[derive(Debug, Parser)] // 在宏里面定义命令行相关的信息
#[command(version = "0.0.1", author = "Alen", about="a command lint tools.")]
struct Cli {
    #[arg(short, long)] // 参数的长短
    name: String,
    #[arg(short, long, default_value = "1")] // 参数的默认值等
    count: u8,
}

fn main() {
    let args = Cli::parse(); // 使用了Parser自动帮Cli这个结构体实现了一些triat
    for _ in 0..args.count {
        println!("{}", args.name);
    }
}

注意:使用宏特性编写命令行程序,在添加依赖时需要增加derive这个特性

运行效果如下所示:

  command_line_demo git:(master)  cargo run -- --name alen --count 2
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.06s
     Running `target/debug/command_line_demo --name alen --count 2`
alen
alen
  command_line_demo git:(master)  

使用 structopt

structopt 是一个基于 clap 的库,提供类似 derive 的功能。它是早期版本的简化方案,功能已逐渐被 clap 的 derive 特性替代,但仍在一些项目中被使用。

基本用法

示例:


use structopt::StructOpt;

#[derive(Debug, StructOpt)] // 在结构体上面使用StructOpt使得Cli拥有了某种trait
#[structopt(name="My Cli app", about="a command lint tools")] // 在宏里面定义命令行相关的信息
struct Cli {
    #[structopt(short, long)]
    name: String,
    #[structopt(short, long)]
    debug: bool,
}

fn main() {
    let args = Cli::from_args(); // 解析命令行
    println!("{:?}", args.name);
    if args.debug {
        println!("{:#?}", args.debug);
    }
}

运行效果如下所示:

  command_line_demo git:(master)  cargo run -- --name alen --debug
   Compiling command_line_demo v0.1.0 (/Users/Alen/Workspaces/Rust/command_line_demo)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.80s
     Running `target/debug/command_line_demo --name alen --debug`
"alen"
true

创建命令行工具的种类

单命令工具

适用于功能简单的工具,所有参数都作用于一个命令。

多子命令工具

适用于功能复杂的工具,每个子命令代表一个功能。

小结

clap 的优势

  • 功能强大且灵活,支持多种方式定义参数(手动、derive 宏)。
  • 适合复杂命令行工具的开发。

structopt 的特点

  • 简洁优雅,但功能已经被 clap 的 derive 取代。

选择标准

  • 如果需要最新功能,建议使用 clap。
  • 如果项目已有 structopt,可以继续使用或迁移到 clap

通过本章的学习,你已经掌握了使用第三方库 clap 和 structopt 创建功能丰富的命令行工具的能力。在下一章中,我们将结合实际项目,把这些知识应用于开发一个完整的命令行程序。

点击这里复制本文地址 以上内容由文彬编程网整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

文彬编程网 © All Rights Reserved.  蜀ICP备2024111239号-4