devlog

Rust でコマンドを実行する

2023-06-12

Rust でコマンドを実行します。

コマンドを実行する

std::process::Command を使います

use std::process::Command; use std::process::Stdio; fn main() { let output = Command::new("echo") .args(["aaa"]) .stdout(Stdio::piped()) .stderr(Stdio::piped()) .output() // コマンドを実行 .unwrap(); println!("{:?}", output); // 実行結果 println!("{}", String::from_utf8_lossy(&output.stdout)); // 標準出力をStringに. }

これを実行します。

$ cargo run Output { status: ExitStatus(unix_wait_status(0)), stdout: "aaa\n", stderr: "" } aaa

非同期に実行する

output() は、コマンドが終わるまで待機します

Command::new("sleep") .args(["10"]) .stdout(Stdio::inherit()) .output() // コマンド実行中は待機する .unwrap();

非同期に実行するには、代わりに spawn() を呼びます

let child = Command::new("echo") .args(["aaa"]) .spawn() .unwrap(); println!("bbb");
$ cargo run bbb aaa

spawn() すると std::process::Child が返ります

std::process::Child で wait する

wait() を呼びます

let mut child = Command::new("echo") .args(["aaa"]) .spawn() .unwrap(); let status = child.wait().unwrap(); println!("{:?}", status);
$ cargo run ExitStatus(unix_wait_status(0))

wait_with_output() を呼ぶと子プロセスの標準出力を得られます

let child = Command::new("echo") .args(["aaa"]) .stdout(Stdio::piped()) .stderr(Stdio::piped()) .spawn() .unwrap(); let output = child.wait_with_output().unwrap(); println!("{:?}", output); println!("{}", String::from_utf8_lossy(&output.stdout));
$ cargo run Output { status: ExitStatus(unix_wait_status(0)), stdout: "aaa\n", stderr: "" } aaa

子プロセスの標準出力を、そのまま流す

Stdio::inherit() を渡すと、子プロセスの標準出力を親プロセスのstdoutにそのまま流せます

Command::new("echo") .args(["aaa"]) .stdout(Stdio::inherit()) // inheritする .output() .unwrap(); println!("bbb");
$ cargo run aaa bbb

これを応用すると、例えば次のようなこともできます

Command::new("node") .stdin(Stdio::inherit()) .stdout(Stdio::inherit()) .stderr(Stdio::inherit()) .output() .unwrap(); println!("hello from rust");
$ cargo run Welcome to Node.js v18.16.0. Type ".help" for more information. > new Date() 2023-06-11T16:38:11.155Z > .exit hello from rust

Node.js のReplを起動できました

  • 作成日
    2023-06-12
  • 更新日
    2024-02-11