Rust进程管理库axoprocess的使用:高效安全的进程控制与交互工具

Rust进程管理库axoprocess的使用:高效安全的进程控制与交互工具

axoprocess是一个提供更友好默认设置来调用CLI命令的Rust库。

安装

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

cargo add axoprocess

或者在Cargo.toml中添加以下行:

axoprocess = "0.2.1"

许可证

axoprocess采用双许可证:

  • Apache License, Version 2.0
  • MIT license

示例代码

以下是使用axoprocess的基本示例:

use axoprocess::Command;

fn main() {
    // 创建一个新命令
    let mut cmd = Command::new("echo");
    
    // 添加参数
    cmd.arg("Hello, world!");
    
    // 执行命令并获取输出
    let output = cmd.output().expect("Failed to execute command");
    
    // 打印命令输出
    println!("Status: {}", output.status);
    println!("Stdout: {}", String::from_utf8_lossy(&output.stdout));
    println!("Stderr: {}", String::from_utf8_lossy(&output.stderr));
}

完整示例

use axoprocess::Command;
use std::process;

fn main() {
    // 示例1: 简单命令执行
    let output = Command::new("ls")
        .arg("-l")
        .arg("-a")
        .output()
        .expect("Failed to execute ls command");
    
    println!("Files in directory:\n{}", String::from_utf8_lossy(&output.stdout));
    
    // 示例2: 管道输入
    let echo = Command::new("echo")
        .arg("hello world")
        .stdout(process::Stdio::piped())
        .spawn()
        .expect("Failed to spawn echo");
    
    let grep = Command::new("grep")
        .arg("hello")
        .stdin(echo.stdout.unwrap())  // 将echo的输出作为grep的输入
        .output()
        .expect("Failed to execute grep command");
    
    println!("Grep result: {}", String::from_utf8_lossy(&grep.stdout));
    
    // 示例3: 设置环境变量
    let env_output = Command::new("printenv")
        .env("MY_VAR", "my_value")
        .output()
        .expect("Failed to execute printenv");
    
    println!("Environment variables:\n{}", String::from_utf8_lossy(&env_output.stdout));
}

特点

  • 提供更友好的默认设置来调用CLI命令
  • 支持命令管道
  • 可以设置环境变量
  • 支持获取命令输出和状态

文档

更多详细用法请参考官方文档

仓库

项目源代码托管在GitHub


1 回复

Rust进程管理库axoprocess的使用:高效安全的进程控制与交互工具

概述

axoprocess 是一个 Rust 语言的进程管理库,提供了高效且安全的进程控制和交互功能。它简化了创建、管理和与子进程交互的过程,同时保持了 Rust 的安全性和性能优势。

主要特性

  1. 跨平台支持(Linux/macOS/Windows)
  2. 安全的进程派生和管理
  3. 灵活的输入/输出控制
  4. 进程组和会话管理
  5. 信号处理和发送
  6. 超时和进程终止控制

安装

在 Cargo.toml 中添加依赖:

[dependencies]
axoprocess = "0.3"

基本用法

创建简单进程

use axoprocess::Command;

fn main() -> std::io::Result<()> {
    let output = Command::new("echo")
        .arg("Hello, axoprocess!")
        .output()?;
    
    println!("Output: {}", String::from_utf8_lossy(&output.stdout));
    Ok(())
}

带输入输出的交互式进程

use axoprocess::{Command, Stdio};
use std::io::Write;

fn main() -> std::io::Result<()> {
    let mut child = Command::new("grep")
        .arg("Rust")
        .stdin(Stdio::piped())
        .stdout(Stdio::piped())
        .spawn()?;
    
    let mut stdin = child.stdin.take().unwrap();
    stdin.write_all(b"Hello Rust\nGoodbye Python\n")?;
    drop(stdin); // 关闭输入
    
    let output = child.wait_with_output()?;
    println!("Found: {}", String::from_utf8_lossy(&output.stdout));
    Ok(())
}

高级功能

进程组和会话控制

use axoprocess::{Command, Session};

fn main() -> std::io::Result<()> {
    // 创建一个新的会话和进程组
    let mut cmd = Command::new("long_running_process");
    let session = Session::new(&mut cmd)?;
    
    // 稍后可以终止整个进程组
    session.kill()?;
    Ok(())
}

超时控制

use axoprocess::Command;
use std::time::Duration;

fn main() -> std::io::Result<()> {
    let mut child = Command::new("slow_process").spawn()?;
    
    match child.wait_timeout(Duration::from_secs(5)) {
        Ok(Some(status)) => println!("Process exited with: {}", status),
        Ok(NNone) => {
            println!("Process timed out, killing it");
            child.kill()?;
            child.wait()?;
        }
        Err(e) => eprintln!("Error: {}", e),
    }
    Ok(())
}

信号处理

use axoprocess::{Command, Signal};

fn main() -> std::io::Result<()> {
    let mut child = Command::new("server").spawn()?;
    
    // 发送SIGTERM信号
    child.signal(Signal::Term)?;
    
    // 等待进程结束
    let status = child.wait()?;
    println!("Process exited with: {}", status);
    Ok(())
}

安全注意事项

  1. 始终检查命令执行结果
  2. 处理子进程的输入/输出时要小心避免死锁
  3. 考虑使用 async 版本处理长时间运行的进程
  4. 在生产环境中添加适当的超时处理

异步支持

axoprocess 也提供了异步接口,可以与 tokio 或 async-std 等运行时集成:

use axoprocess::AsyncCommand;
use tokio::io::AsyncWriteExt;

#[tokio::main]
async fn main() -> std::io::Result<()> {
    let mut child = AsyncCommand::new("sort")
        .stdin(std::process::Stdio::piped())
        .stdout(std::process::Stdio::piped())
        .spawn_async()?;
    
    let mut stdin = child.stdin.take().unwrap();
    stdin.write_all(b"banana\napple\ncherry\n").await?;
    drop(stdin);
    
    let output = child.wait_with_output().await?;
    println!("Sorted:\n{}", String::from_utf8_lossy(&output.stdout));
    Ok(())
}

完整示例

下面是一个结合多个功能的完整示例,展示如何使用 axoprocess 创建、管理和交互进程:

use axoprocess::{Command, Session, Signal, Stdio};
use std::time::Duration;
use std::io::Write;

fn main() -> std::io::Result<()> {
    // 示例1: 简单进程创建
    println!("--- 简单进程示例 ---");
    let output = Command::new("echo")
        .arg("Hello from simple process")
        .output()?;
    println!("简单进程输出: {}", String::from_utf8_lossy(&output.stdout));

    // 示例2: 交互式进程
    println!("\n--- 交互式进程示例 ---");
    let mut child = Command::new("grep")
        .arg("important")
        .stdin(Stdio::piped())
        .stdout(Stdio::piped())
        .spawn()?;
    
    child.stdin.as_mut().unwrap()
        .write_all(b"normal line\nimportant line\nanother line\n")?;
    
    let output = child.wait_with_output()?;
    println!("筛选结果: {}", String::from_utf8_lossy(&output.stdout));

    // 示例3: 进程组控制
    println!("\n--- 进程组控制示例 ---");
    let mut cmd = Command::new("sleep")
        .arg("60");
    let session = Session::new(&mut cmd)?;
    println!("创建了新会话,进程组ID: {}", session.id());
    session.kill()?;
    println!("已终止整个进程组");

    // 示例4: 超时控制
    println!("\n--- 超时控制示例 ---");
    let mut child = Command::new("sleep")
        .arg("10")
        .spawn()?;
    
    match child.wait_timeout(Duration::from_secs(1)) {
        Ok(Some(status)) => println!("进程退出状态: {}", status),
        Ok(None) => {
            println!("进程超时,正在终止...");
            child.kill()?;
            child.wait()?;
            println!("进程已终止");
        }
        Err(e) => eprintln!("错误: {}", e),
    }

    // 示例5: 信号处理
    println!("\n--- 信号处理示例 ---");
    let mut child = Command::new("yes")
        .spawn()?;
    
    std::thread::sleep(Duration::from_secs(1));
    child.signal(Signal::Term)?;
    println!("已发送SIGTERM信号");
    
    Ok(())
}

总结

axoprocess 提供了强大而安全的进程管理功能,适合需要精细控制子进程的 Rust 应用程序。它结合了 Rust 的安全性和系统编程能力,使得进程管理既简单又可靠。通过本文的示例和说明,您应该能够开始使用 axoprocess 来管理您的 Rust 应用程序中的子进程。

回到顶部