shleazy/
lib.rs

1use anyhow::{anyhow, Result};
2use log::debug;
3use std::ffi::OsStr;
4use std::process::Command;
5
6/// Get exit code, print the output to stdout as it goes
7pub fn getstatus<S, I>(exec: S, args: I) -> Result<i32>
8where
9    S: AsRef<OsStr>,
10    I: IntoIterator,
11    I::Item: AsRef<OsStr>,
12{
13    let mut process = Command::new(exec);
14    for a in args {
15        process.arg(a);
16    }
17
18    debug!("Running command: {:?}", process);
19
20    let exit_status = process.status()?;
21    let code = exit_status
22        .code()
23        .ok_or(anyhow!("Unable to get exit code"))?;
24    Ok(code)
25}
26
27/// Same as getstatus, but wrap in a shell invocation
28pub fn getstatus_shell<S: AsRef<OsStr>>(command: S) -> Result<i32> {
29    getstatus("/bin/sh", [OsStr::new("-c"), OsStr::new(&command)])
30}
31
32/// Capture status and output
33pub fn getstatusoutput<S, I>(exec: S, args: I) -> Result<(i32, Vec<u8>)>
34where
35    S: AsRef<OsStr>,
36    I: IntoIterator,
37    I::Item: AsRef<OsStr>,
38{
39    let mut process = Command::new(exec);
40    for a in args {
41        process.arg(a);
42    }
43
44    debug!("Running command: {:?}", process);
45
46    let output = process.output()?;
47    let code = output
48        .status
49        .code()
50        .ok_or(anyhow!("Unable to get exit code"))?;
51
52    Ok((code, output.stdout))
53}
54
55/// Same as getstatusoutput, but wrap in a shell invocation
56pub fn getstatusoutput_shell<S: AsRef<OsStr>>(command: S) -> Result<(i32, Vec<u8>)> {
57    getstatusoutput("/bin/sh", [OsStr::new("-c"), OsStr::new(&command)])
58}
59
60/// Return Err if non-zero exit code
61pub fn run_shell_or_err<S: AsRef<OsStr> + std::fmt::Display>(command: S) -> Result<()> {
62    match getstatus_shell(&command) {
63        Ok(0) => return Ok(()),
64        _ => Err(anyhow!("Error with command: {}", &command)),
65    }
66}
67
68/// Return Err if non-zero exit code
69pub fn getoutput_shell_or_err<S: AsRef<OsStr> + std::fmt::Display>(command: S) -> Result<Vec<u8>> {
70    match getstatusoutput_shell(&command) {
71        Ok((0, output)) => return Ok(output),
72        Ok((code, output)) => Err(anyhow!(
73            "Error with command: Command: {}\nCode: {}\nOutput: {:?}",
74            &command,
75            code,
76            output
77        )),
78        _ => Err(anyhow!("Error with command: {}", &command)),
79    }
80}