Hi. Normally, Rust makes it difficult to accidentally write buggy code. This is one of its great strengths. However, the API of output() on std::process::Command API has two serious error handling hazards:
- It requires the user to explicitly fish out the program's exit status and check it.
- It requires the user to explicitly deal, somehow, with the program's stderr output (if any).
See the example below.
I think this is very difficult to fix with the current return value from output(). It seems to me that there should be a new function whose behaviour is as follows:
- Unless the user explictly called
.stderr(...) when building the Command, any nonempty stderr is treated as an error, giving an Err return value (whose Debug impl prints the stderr output).
- Nonzero exit status is treated as an error, giving an
Err return value,
- In case of nonzero exit status together with nonempty stderr output (the usual case) the error object contains both (and its
Debug impl displays both).
- The returned value is purely the actual stdout.
I don't know what this should be called. Unfortunately the name output has been taken for the more hazardous, raw, function. Which we must retain because if you want to run a command that sometimes succeeds returning nonzero (eg, diff) you need something like it.
(See also #70186 which is about the return value from spawn(). I am about to file another issue about the return value from wait())
use std::process::*;
use std::io::stdout;
use std::io::Write;
fn main() {
let command = ["ls","--no-such-option"];
let output = Command::new(command[0])
.args(&command[1..])
.output()
.expect("output() failed");
println!("Output from {:?}:", &command);
stdout().write_all(output.stdout.as_slice()).expect("write failed");
println!("All went well!")
}
(Playground)
Actual output:
Compiling playground v0.0.1 (/playground)
Finished dev [unoptimized + debuginfo] target(s) in 0.72s
Running `target/debug/playground`
Standard Output
Output from ["ls", "--no-such-option"]:
All went well!
Expected output:
Some kind of compiler warning. Or something in the docs to say not to use .output() (and, therefore, something convenient to use instead).
Hi. Normally, Rust makes it difficult to accidentally write buggy code. This is one of its great strengths. However, the API of
output()onstd::process::CommandAPI has two serious error handling hazards:See the example below.
I think this is very difficult to fix with the current return value from
output(). It seems to me that there should be a new function whose behaviour is as follows:.stderr(...)when building theCommand, any nonempty stderr is treated as an error, giving anErrreturn value (whoseDebugimpl prints the stderr output).Errreturn value,Debugimpl displays both).I don't know what this should be called. Unfortunately the name
outputhas been taken for the more hazardous, raw, function. Which we must retain because if you want to run a command that sometimes succeeds returning nonzero (eg,diff) you need something like it.(See also #70186 which is about the return value from
spawn(). I am about to file another issue about the return value fromwait())(Playground)
Actual output:
Expected output:
Some kind of compiler warning. Or something in the docs to say not to use
.output()(and, therefore, something convenient to use instead).