#command #macro #proc-macro #cmd #process #script #shell

cmd-macro

使 std::process::Command 的使用变得简单

3个版本

0.1.2 2020年5月17日
0.1.1 2020年5月10日
0.1.0 2020年5月10日

#553 in 过程宏

MIT 许可证

32KB
653

cmd

Build Status Latest Version Rust Documentation

此crate提供了一个宏,帮助使用Rust的 std::process::Command 功能。(需要rust nightly版)

[dependencies]
cmd-macro = "0.1"

用法

要安装nightly版本,请使用rustup

rustup default nightly
#![feature(proc_macro_hygiene)]

use cmd_macro::cmd;

fn main() {
    let who = "world";
    let output = cmd!(echo hello #who ##who).unwrap();
    let output = String::from_utf8(output.stdout).unwrap();
    assert_eq!(output, "hello world #who\n");

    let s = "seq";
    let n = 3;
    let output = cmd!(#s #{2 * n}).unwrap();
    let output = String::from_utf8(output.stdout).unwrap();
    assert_eq!(output, "1\n2\n3\n4\n5\n6\n");
}

这将展开为

fn main() {
    let who = "world";
    let output = (|| -> std::io::Result<std::process::Output> {
        let x0 = std::process::Command::new("echo")
            .arg("hello")
            .arg(format!("{}", who))
            .arg("#who")
            .output()?;
        Ok(x0)
    })()
    .unwrap();
    let output = String::from_utf8(output.stdout).unwrap();
    assert_eq!(output, "hello world #who\n");
    
    let s = "seq";
    let n = 3;
    let output = (|| -> std::io::Result<std::process::Output> {
        let x0 = std::process::Command::new(format!("{}", s))
        .arg(format!("{}", 2 * n))
        .output()?;
        Ok(x0)
    })()
    .unwrap();
    let output = String::from_utf8(output.stdout).unwrap();
    assert_eq!(output, "1\n2\n3\n4\n5\n6\n");
}

也支持有限的管道操作

let cargo_files = cmd!(ls | grep "Cargo").unwrap();
let cargo_files = String::from_utf8(cargo_files.stdout).unwrap();
assert_eq!(cargo_files, "Cargo.lock\nCargo.toml\n");

它将被解析为

let cargo_files = (|| -> std::io::Result<std::process::Output> {
    let x0 = std::process::Command::new("ls")
        .stdout(std::process::Stdio::piped())
        .spawn()?;
    let x1 = std::process::Command::new("ls")
        .stdin(x0.stdout.unwrap())
        .output()?;
    Ok(x1)
})()
.unwrap();
let cargo_files = String::from_utf8(cargo_files.stdout).unwrap();
assert_eq!(cargo_files, "Cargo.lock\nCargo.toml\n");

依赖

~1.5MB
~35K SLoC