When I try to start cmd.exe
by the following code:
use std::process::{Command, Stdio};
use std::io::{BufRead, Write, BufReader};
fn main() {
let mut child_cmd = Command::new("cmd.exe")
// seems it work well with `/bin/bash` in Linux
.stdin(Stdio::piped())
.stdout(Stdio::piped()) // Error emitted here.
.spawn()
.unwrap();
// do sth. else
}
I want to redirect the output to pipeline, but it always report The process tried to write to a nonexistent pipe
; when I removed .stdout(Stdio::piped())
, no errors thrown. Why does this happen?
EvilTak's comment is spot on. When you redirect STDOUT to a pipe, you'll also have to redirect STDERR to a pipe. The following code no longer errors out:
use std::process::{Command, Stdio};
fn main() {
let mut child_cmd = Command::new("cmd.exe")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped()) // Required when redirecting stdout
.spawn()
.unwrap();
// do sth. else
}
While that fixes the immediate issue, I'm not sure what actually causes it. Looking at the CreateProcessW function and the STARTUPINFOW structure it accepts, it looks as though standard I/O redirection is an all-or-nothing option, designated by the STARTF_USESTDHANDLES
flag.
The fact that Python exhibits the same behavior suggests that this is in fact a peculiarity of either the Windows API or cmd.exe's implementation.
Either way, I have not done any extensive research to figure out what exactly is going on here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With