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