Add a way to get stdout/err from processes that exit with a non-zero status
This can be done through use of unchecked today, but it would be great to have an ergonomic way to do so given how much duct is built around making the correct thing easier to do.
The main challenge is that wait() etc return a &Output, while Rust errors are generally 'static. stdout and stderr are unbounded so if we clone data, it can be quite expensive.
Some thoughts:
- allow opting into printing out stdout/stderr, have it turned off by default
- as part of opting in, specify a beginning and end length, truncating the output in the middle
- the data is UTF-8 in many cases, but it might not be, have some handling around that:
- truncation will need special handling around multibyte UTF-8 sequences given that the main purpose is to print out data
- assume that if someone's asking for output to be returned, they generally expect it to be UTF-8 and just use
String::from_utf8_lossywhile printing the data out
- use a custom error type for clients that care about it, and add a conversion to
io::Errorthrough aFromimpl for compatibility
Could you give me an example of what you're imagining the API might look like, and compare that to doing the same thing with unchecked today?
Digging up this thread - I want to run a command that will print its errors to stderr. I'd love to be able to do something like
let result = cmd!(...).run();
match result {
Ok(output) => { ... },
Error(err) => {
eprintln!("{}", err.stderr);
// ...
},
}
// vs unchecked
let result = cmd!(...).unchecked().run()?;
if result.status.success() { ... }
else {
eprintln!("{}", err.stderr);
}
It's definitely doable via unchecked but as OP said duct is about doing commands the right way. To me, at least, dropping the (likely) root cause error messages from the command when the command fails by default seems wrong? To me at least I think that the rare case is wanting to just tell the user "this command failed" as opposed to "this command failed and here's why".