Rust命令行工具扩展库nu-command的使用,nu-command为Nushell提供强大的内置命令集和插件功能

Rust命令行工具扩展库nu-command的使用,nu-command为Nushell提供强大的内置命令集和插件功能

内部Nushell库

这个crate包含Nushell的大部分命令。根据需要可以将nu-command中的一些命令移动到nu-cmd-* crates中。

这个crate实现了Nushell的核心组件,主要设计用于Nushell内部使用,而不是直接支持插件开发或其他用户场景。

安装

在项目目录中运行以下Cargo命令:

cargo add nu-command

或者在Cargo.toml中添加以下依赖项:

nu-command = "0.106.1"

示例使用

以下是内容中提供的示例代码:

use nu_command::commands::*;
use nu_protocol::Value;

fn main() {
    // 创建一个新的命令集合
    let commands = CommandCollection::new();
    
    // 执行一个简单的命令
    let result = commands.execute("ls", &[]);
    
    // 处理结果
    match result {
        Ok(Value::List { vals, .. }) => {
            println!("Found {} items:", vals.len());
            for item in vals {
                println!("- {}", item);
            }
        }
        Ok(value) => println!("Result: {}", value),
        Err(err) => eprintln!("Error: {}", err),
    }
}

完整示例demo

以下是一个扩展的完整示例,展示更多nu-command的功能:

use nu_command::commands::*;
use nu_protocol::{Value, Span};
use nu_engine::command::Command;

fn main() {
    // 初始化命令集合
    let mut commands = CommandCollection::new();
    
    // 注册自定义命令
    commands.add_command("greet", Box::new(GreetCommand));
    
    // 执行内置命令
    let ls_result = commands.execute("ls", &[]);
    handle_result("ls", ls_result);
    
    // 执行自定义命令
    let greet_result = commands.execute("greet", &[Value::string("World", Span::unknown())]);
    handle_result("greet", greet_result);
    
    // 尝试执行不存在的命令
    let invalid_result = commands.execute("invalid_cmd", &[]);
    handle_result("invalid_cmd", invalid_result);
}

fn handle_result(cmd: &str, result: Result<Value, Box<dyn std::error::Error>>) {
    match result {
        Ok(Value::List { vals, .. }) => {
            println!("{} command returned {} items:", cmd, vals.len());
            for item in vals {
                println!("- {}", item);
            }
        }
        Ok(value) => println!("{} command result: {}", cmd, value),
        Err(err) => eprintln!("Error executing {}: {}", cmd, err),
    }
}

// 自定义命令实现
struct GreetCommand;

impl Command for GreetCommand {
    fn name(&self) -> &str {
        "greet"
    }

    fn usage(&self) -> &str {
        "Greets the given name"
    }

    fn signature(&self) -> nu_protocol::Signature {
        nu_protocol::Signature::build("greet")
            .required("name", nu_protocol::SyntaxShape::String, "Name to greet")
    }

    fn run(
        &self,
        _engine_state: &nu_engine::EngineState,
        _stack: &mut nu_engine::Stack,
        call: &nu_protocol::ast::Call,
        _input: nu_protocol::PipelineData,
    ) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
        let name: String = call.req(_engine_state, _stack, 0)?;
        Ok(Value::String {
            val: format!("Hello, {}!", name),
            span: call.head,
        }
        .into_pipeline_data())
    }
}

文档

更多详细使用文档可参考官方文档。

仓库

源代码可在GitHub仓库查看。


1 回复

Rust命令行工具扩展库nu-command的使用

介绍

nu-command是Nushell项目的核心命令库,为Nushell提供了一套强大的内置命令集和插件功能。Nushell是一个用Rust编写的现代shell,而nu-command则是其命令实现的基础库。

主要功能

  1. 提供Nushell的核心命令集
  2. 支持命令插件扩展
  3. 包含文件操作、系统信息、数据处理等实用命令
  4. 支持管道操作和流式处理

使用方法

基本命令使用

// 在Nushell中使用ls命令
ls | where size > 1kb

// 使用sort-by命令排序
ls | sort-by modified

// 使用group-by分组
ls | group-by type

创建自定义命令

// 在Rust中创建一个简单的nu-command插件
use nu_protocol::{Signature, Value};
use nu_engine::Command;

struct HelloWorld;

impl Command for HelloWorld {
    fn name(&self) -> &str {
        "hello"
    }

    fn signature(&self) -> Signature {
        Signature::build("hello")
    }

    fn usage(&self) -> &str {
        "Prints 'Hello, world!'"
    }

    fn run(
        &self,
        engine_state: &nu_engine::EngineState,
        stack: &mut nu_engine::Stack,
        call: &nu_protocol::ast::Call,
        input: nu_protocol::PipelineData,
    ) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
        println!("Hello, world!");
        Ok(input)
    }
}

数据处理示例

// 在Nushell中使用nu-command命令处理数据
open data.csv 
| where price > 100 
| select product price 
| sort-by price 
| to json

系统信息命令

// 获取系统信息
sys

// 获取CPU信息
sys cpu

// 获取内存使用情况
sys mem

插件开发

要开发nu-command插件,你需要:

  1. 创建一个新的Rust库项目
  2. 添加nu-command和nu-engine作为依赖
  3. 实现Command trait
  4. 注册你的命令

示例Cargo.toml依赖:

[dependencies]
nu-command = "0.60"  # 使用最新版本
nu-engine = "0.60"
nu-protocol = "0.60"

完整示例Demo

下面是一个完整的nu-command插件开发示例,实现了一个简单的计算器命令:

//! 一个简单的nu-command计算器插件示例

use nu_engine::Command;
use nu_protocol::{
    ast::Call,
    engine::{EngineState, Stack},
    Category, Example, IntoPipelineData, PipelineData, ShellError, Signature, Span, Type, Value,
};

// 定义Calculator命令结构体
#[derive(Clone)]
pub struct Calculator;

impl Command for Calculator {
    fn name(&self) -> &str {
        "calc"
    }

    fn signature(&self) -> Signature {
        Signature::build("calc")
            .input_output_types(vec![(Type::Nothing, Type::Int)])
            .required("expression", SyntaxShape::String, "数学表达式")
            .category(Category::Math)
    }

    fn usage(&self) -> &str {
        "计算数学表达式"
    }

    fn examples(&self) -> Vec<Example> {
        vec![Example {
            description: "计算简单的加法",
            example: "calc '2 + 2'",
            result: Some(Value::test_int(4)),
        }]
    }

    fn run(
        &self,
        engine_state: &EngineState,
        stack: &mut Stack,
        call: &Call,
        _input: PipelineData,
    ) -> Result<PipelineData, ShellError> {
        // 获取表达式参数
        let expression: String = call.req(engine_state, stack, 0)?;
        
        // 简单的表达式计算逻辑
        let result = match evaluate_expression(&expression) {
            Ok(val) => val,
            Err(err) => return Err(ShellError::GenericError {
                error: "计算错误".into(),
                msg: err,
                span: Some(call.head),
                help: None,
                inner: vec![],
            }),
        };

        // 返回计算结果
        Ok(Value::int(result, call.head).into_pipeline_data())
    }
}

// 简单的表达式计算函数
fn evaluate_expression(expr: &str) -> Result<i64, String> {
    // 这里使用简单的eval方式,生产环境应该使用更安全的解析器
    let result = meval::eval_str(expr)
        .map_err(|e| format!("无法计算表达式: {}", e))?;
    
    Ok(result as i64)
}

// 注册命令
pub fn create_command() -> Box<dyn Command> {
    Box::new(Calculator)
}

对应的Cargo.toml配置:

[package]
name = "nu-plugin-calculator"
version = "0.1.0"
edition = "2021"

[dependencies]
nu-command = "0.60"
nu-engine = "0.60"
nu-protocol = "0.60"
meval = "0.2"  # 用于简单数学表达式计算

优势

  1. 高性能:基于Rust构建,执行效率高
  2. 类型安全:利用Rust的类型系统保证命令安全性
  3. 可扩展:易于添加自定义命令
  4. 跨平台:支持Windows、macOS和Linux

nu-command是Nushell强大功能的基础,无论是使用内置命令还是开发自定义插件,都能显著提升shell的使用体验和生产力。

回到顶部