Last active
February 7, 2024 17:49
-
-
Save pkozelka/3514f8ba2a5fcb9992ef6ee001747a5d to your computer and use it in GitHub Desktop.
Process execution in Rust
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::path::Path; | |
use std::process::Stdio; | |
use tokio::io::BufReader; | |
use tokio::io::AsyncBufReadExt; | |
use tokio::process::Command; | |
use tokio::sync::mpsc; | |
/// Execute a process, gather its mixed outputs into stdout | |
/// | |
pub async fn execute<P: AsRef<Path>>(executable: P, args: Vec<&'static str>) { | |
let mut process = Command::new(executable.as_ref()) | |
.args(&args) | |
.stdout(Stdio::piped()) | |
.stderr(Stdio::piped()) | |
.spawn() | |
.unwrap(); | |
println!("Executing {:?}", process); | |
let (tx, mut rx) = mpsc::channel(1000); | |
{ // spawn a task that reads standard output | |
let tx = tx.clone(); | |
let stdout = process.stdout.take().unwrap(); | |
tokio::spawn(async move { | |
let mut lines = BufReader::new(stdout).lines(); | |
while let Some(line) = lines.next_line().await.unwrap() { | |
tx.send(format!("- {}", line)).await.unwrap(); | |
} | |
}); | |
} | |
{ // spawn a task that reads standard error | |
let stderr = process.stderr.take().unwrap(); | |
tokio::spawn(async move { | |
let mut lines = BufReader::new(stderr).lines(); | |
while let Some(line) = lines.next_line().await.unwrap() { | |
tx.send(format!("! {}", line)).await.unwrap(); | |
} | |
}); | |
} | |
// mix all the outputs | |
while let Some(line) = rx.recv().await { | |
println!("{}", line); | |
} | |
let exit_status = process.wait().await.unwrap(); | |
println!("exit code: {}", exit_status); | |
} | |
#[tokio::main] | |
async fn main() { | |
execute("find", vec!("/", "-name", "*.sh")).await; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::path::Path; | |
use std::process::Stdio; | |
use tokio::io::BufReader; | |
use tokio::io::AsyncBufReadExt; | |
use tokio::process::Command; | |
pub async fn execute<P: AsRef<Path>>(executable: P, args: Vec<&'static str>) { | |
let mut process = Command::new(executable.as_ref()) | |
.args(&args) | |
.stdout(Stdio::piped()) | |
.stderr(Stdio::null()) | |
.spawn() | |
.unwrap(); | |
{ | |
let stdout = process.stdout.take().unwrap(); | |
let reader = BufReader::new(stdout); | |
let mut lines = reader.lines(); | |
while let Some(line) = lines.next_line().await.unwrap() { | |
println!("STDOUT: {}", line); | |
} | |
} | |
let exit_status = process.wait().await.unwrap(); | |
println!("exit code: {}", exit_status); | |
} | |
#[tokio::main] | |
async fn main() { | |
execute("find", vec!("/", "-name", "*.sh")).await; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::io::{BufRead, BufReader}; | |
use std::path::Path; | |
use std::process::{Command, Stdio}; | |
pub fn execute<P: AsRef<Path>>(executable: P, args: Vec<&'static str>) { | |
let mut cmd = Command::new(executable.as_ref()) | |
.args(&args) | |
.stdout(Stdio::piped()) | |
.stderr(Stdio::null()) | |
.spawn() | |
.unwrap(); | |
{ | |
let stdout = cmd.stdout.as_mut().unwrap(); | |
let reader = BufReader::new(stdout); | |
let lines = reader.lines(); | |
for line in lines { | |
println!("Read: {:?}", line); | |
} | |
} | |
cmd.wait().unwrap(); | |
} | |
fn main() { | |
execute("find", vec!("/", "-name", "*.sh")); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment