#shell #command #cmd

bin+lib run_shell

用 Rust 编写的 shell 脚本

10 个版本

使用旧 Rust 2015

0.1.13 2022 年 8 月 17 日
0.1.12 2022 年 8 月 14 日
0.1.11 2022 年 7 月 10 日
0.1.6 2022 年 6 月 20 日
0.1.4 2022 年 5 月 13 日

#1702开发工具

Download history 160/week @ 2024-03-06 60/week @ 2024-03-13 74/week @ 2024-03-20 66/week @ 2024-03-27 70/week @ 2024-04-03 72/week @ 2024-04-10 100/week @ 2024-04-17 117/week @ 2024-04-24 47/week @ 2024-05-01 81/week @ 2024-05-08 86/week @ 2024-05-15 82/week @ 2024-05-22 71/week @ 2024-05-29 71/week @ 2024-06-05 98/week @ 2024-06-12 36/week @ 2024-06-19

292 每月下载量
用于 nutek

MIT 许可证

33KB
700

run_shell - 用 Rust 编写的 shell 脚本。

run_shell 是 std::process::Command 的辅助库,用于在 Rust 中编写类似任务的 shell 脚本。该库仅适用于类 Unix 操作系统。

运行命令

extern crate run_shell;
use run_shell::*;

// Run command by cmd! macro
cmd!("echo Hello rust run_shell!").run().unwrap();

// Contain white space or non-alphabetical characters
cmd!("echo \"%$#\"").run().unwrap();

// Pass an argument
let name = "run_shell";
cmd!("echo Hello rust {}!", name).run().unwrap();

// Extract environment variable
cmd!("echo HOME is $HOME").run().unwrap();

ShellResult

当命令成功运行且执行代码为 0 时,ShellCommand#run() 的返回值是 ShellResult,它是 Ok(_),因此您可以使用 ? 操作符来检查命令是否成功退出。

extern crate run_shell;
use run_shell::*;

fn shell_function() -> ShellResult {
  cmd!("echo Command A").run()?;
  cmd!("echo Command B").run()?;
  run_shell::ok()
}

输出字符串

ShellCommand 有一个简写来获取 stdout 作为 UTF8 字符串。

extern crate run_shell;
use run_shell::*;

assert_eq!(cmd!("echo OK").stdout_utf8().unwrap(), "OK\n");

Spawn

ShellCommand 有 spawn() 方法,该方法异步运行命令并返回 ShellChild

extern crate run_shell;
use run_shell::*;
extern crate libc;

// Wait
let child = cmd!("sleep 2").spawn().unwrap();
child.wait().unwrap();

// Signal
let child = cmd!("sleep 2").spawn().unwrap();
let result = child.wait();
assert!(result.status().is_ok(), "Still able to obtain status");

线程

如果您想异步运行一系列命令,shell::spawn 将创建一个线程以及 std::thread::spawn,但它返回 ShellHandle 包装 std::thread::JoinHandle

ShellHandle#signal() 用于向线程上运行的过程发送信号。它还通过 ShellComamnd::run() 停止在该线程上启动新的进程。

extern crate run_shell;
use run_shell::*;
extern crate libc;

let handle = run_shell::spawn(|| -> ShellResult {
  cmd!("sleep 3").run()
});
let result = handle.join().unwrap();
assert!(result.status().is_ok(), "Still able to obtain status");

信号处理

trap_signal_and_wait_children() 开始监视 SIGINT 和 SIGTERM,并在收到这些信号时等待所有子进程,然后退出进程。该函数需要在启动任何新线程之前调用。

extern crate run_shell;
use run_shell::*;
run_shell::trap_signal_and_wait_children().unwrap();

访问底层对象

ShellComamnd 包装了 std::process::Command,而 ShellChild 包装了 std::process::Child。这两个底层对象都可以通过公共字段访问。

extern crate run_shell;
use run_shell::*;
use std::process::Stdio;
use std::io::Read;

 // Access std::process::Command.
    let mut shell_command = cmd!("echo OK");
    {
        let command = &mut shell_command.command;
        command.stdout(Stdio::piped());
    }

    // Access std::process::Child.
    let shell_child = shell_command.spawn().unwrap();
    {
        let mut lock = shell_child.0.write().unwrap();
        let child = &mut lock.as_mut().unwrap().child;
        let mut str = String::new();
        child
            .stdout
            .as_mut()
            .unwrap()
            .read_to_string(&mut str)
            .unwrap();
    }
    shell_child.wait().unwrap();

依赖关系

约4.5MB
约95K SLoC