shell_command/
lib.rs

1#[macro_use]
2extern crate failure;
3
4use failure::Error;
5use std::process::Command;
6use std::process::Output;
7
8/// Represents a failed command (non-zero satus)
9#[derive(Fail, Debug)]
10#[fail(display = "Command failed: {}, output: {:?}", command, output)]
11pub struct CommandFail {
12	command: String,
13	output: Output,
14}
15
16impl CommandFail {
17	/// The casted command that has failed
18	pub fn command(&self) -> &str {
19		&self.command
20	}
21
22	/// The command output
23	pub fn output(&self) -> &Output {
24		&self.output
25	}
26}
27
28type Result<T> = std::result::Result<T, Error>;
29
30/// Runs the provided shell command, can return a CommandFail or other lower level errors (using failure)
31pub fn run_shell_command(cmd: &str) -> Result<String> {
32	let output = if cfg!(target_os = "windows") {
33		// untested
34		Command::new("cmd").arg("/C").arg(cmd).output()?
35	} else {
36		Command::new("sh").arg("-c").arg(cmd).output()?
37	};
38	if output.status.success() {
39		Ok(String::from_utf8(output.stdout)?)
40	} else {
41		Err(CommandFail {
42			command: cmd.into(),
43			output,
44		}
45		.into())
46	}
47}