Skip to content

Instantly share code, notes, and snippets.

@stinkymonkeyph
Created December 10, 2023 03:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stinkymonkeyph/2e62ff2681e9c40b9dc441a4a6faa8c6 to your computer and use it in GitHub Desktop.
Save stinkymonkeyph/2e62ff2681e9c40b9dc441a4a6faa8c6 to your computer and use it in GitHub Desktop.
Async shell command execution using tokio runtime
use std::process::Stdio;
use tokio::{process::{Child, Command as TokioCommand, ChildStdout, ChildStderr}, io::BufReader};
use crate::errors::provisioner_errors::ProvisionerError;
pub struct Shell {
pub command: String
}
impl Shell {
pub async fn execute(&self) -> Result<(), ProvisionerError> {
println!("shell_execute: attempting to excute command -> {}", self.command);
let mut command_output: Child = TokioCommand::new("sh")
.args(&["-c", &self.command.as_str()])
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.expect("shell_execute: failed to start command execution");
if let Some(stdout) = command_output.stdout.take() {
let mut stdout_reader: BufReader<ChildStdout> = BufReader::new(stdout);
tokio::spawn(async move {
let mut stdout_writer = tokio::io::stdout();
if let Err(e) = tokio::io::copy_buf(&mut stdout_reader, &mut stdout_writer).await {
eprintln!("shell_execute: error copying stdout: {}", e);
}
});
}
if let Some(stderr) = command_output.stderr.take() {
let mut stderr_reader: BufReader<ChildStderr> = BufReader::new(stderr);
tokio::spawn(async move {
let mut stderr_writer = tokio::io::stderr();
if let Err(e) = tokio::io::copy_buf(&mut stderr_reader, &mut stderr_writer).await {
eprintln!("shell_execute: error copying stderr: {}", e);
}
});
}
let command_status = command_output
.wait()
.await
.expect("shell_execute: failed to wait for command execution");
if command_status.success() {
println!("shell_execute: command executed successfully -> {:?}", self.command);
} else {
return Err(ProvisionerError::ExecuteShellCommandFailedWithError(command_status.code().unwrap_or_default().to_string()))
}
Ok(())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment