mitoo 0.3.0

mitoo is a Rust toolkit library that encapsulates methods such as configuration reading, file operations, encryption and decryption, transcoding, regular expressions, threading, collections, trees, sqlite, rabbitMQ, etc., and customizes or integrates various Util tool classes.
Documentation
use std::process::Command;

/// Command-line tools
///
/// ```plain
/// Command::new(program):创建一个新的命令对象,program 是要执行的命令名称或路径
/// .arg(arg):添加命令参数
/// .args(args):添加多个命令参数(接收迭代器)
/// .output():执行命令并捕获输出(stdout/stderr)和退出状态
/// .status():执行命令并仅获取退出状态(输出直接传递给父进程)
/// .spawn():启动命令但不等待其完成(返回 Child 结构体,可手动控制)
/// .env(key, value):设置环境变量
/// .current_dir(path):设置命令执行的工作目录
/// ```
pub struct CmdUtil;

impl CmdUtil {

    /// 运行命令
    ///
    /// cmd: 数组方式的命令,第一个元素是命名执行程序
    ///
    /// ```rust
    /// use mitoo::CmdUtil;
    ///
    /// CmdUtil::run_cmd(vec!["ffmpeg", "-i", "input.mp4", "output.mp4"])
    /// ```
    pub fn run_cmd(cmd: Vec<&str>) -> Result<String, String> {
        if cmd.len() > 0 {
            let full_command_line = cmd.join(" ").to_string();
            let mut c = Command::new(cmd[0]);
            if cmd.len() > 1 {
                c.args(&cmd[1..]);
            }
            // 执行命令并捕获输出
            let output = c.output().expect("请检查命令是否正确,或是否具备执行权限或环境变量等!");
            // 处理命令执行结果
            if output.status.success() {
                println!("命令执行成功: \n{}", full_command_line);
                // 可选:打印ffmpeg输出信息
                let stdout = String::from_utf8_lossy(&output.stdout);
                println!("命令输出:\n{}", stdout);
                return Ok(stdout.to_string());
            } else {
                println!("命令执行失败: \n{}", full_command_line);
                // 打印错误信息
                let stderr = String::from_utf8_lossy(&output.stderr);
                println!("错误信息:\n{}", stderr);
                return Ok(stderr.to_string());
            }
        }
        Err("没有命令".to_string())
    }

    /// TODO 未测试过
    pub fn run_script(script_path: &str) -> std::io::Result<()> {
        #[cfg(windows)]
        let status = Command::new("cmd.exe")
            .arg("/c")
            .arg(script_path)  // Windows 批处理脚本路径
            .status()?;
    
        #[cfg(not(windows))]
        let status = Command::new("/bin/sh")
            .arg(script_path)  // Unix Shell 脚本路径
            .status()?;
    
        println!("脚本执行状态: {}", status);
        Ok(())
    }

    /// TODO 未测试过
    pub fn run_script_with_params(script_path: &str, params: Vec<&str>) -> std::io::Result<()> {
        #[cfg(windows)]
        let status = Command::new("cmd.exe")
            .arg("/c")
            .arg(script_path)  // Windows 批处理脚本路径
            .args(&params)
            .status()?;
    
        #[cfg(not(windows))]
        let status = Command::new("/bin/sh")
            .arg(script_path)  // Unix Shell 脚本路径
            .args(&params)
            .status()?;
    
        println!("脚本执行状态: {}", status);
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_run_cmd() {
        // 在 Windows 上使用 cmd.exe 执行 cd 命令
        // let result = Command::new("cmd.exe")
        //     .arg("/c")
        //     .arg("cd /d D:/Environment && dir")  // 可以追加其他命令查看效果
        //     .status()
        //     .expect("执行命令失败");

        let cmd = vec!["cmd.exe", "/c", "cd", "/d", "d:/Environment/"];
        let res = CmdUtil::run_cmd(cmd);
        println!("{:?}", res);

        let cmd = vec!["ffmpeg"];
        let res = CmdUtil::run_cmd(cmd);
        println!("{:?}", res);
    }
}