为什么我不能在 Rust 中将 `Stdio::piped()` 与 windows `cmd.exe` 一起使用?
Why I can't use `Stdio::piped()` with windows `cmd.exe` in Rust?
当我尝试通过以下代码启动 cmd.exe
时:
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
}
我想将输出重定向到管道,但它总是报告 The process tried to write to a nonexistent pipe
;当我删除 .stdout(Stdio::piped())
时,没有抛出任何错误。为什么会这样?
EvilTak 的 恰到好处。当您将 STDOUT 重定向到管道时,您还必须将 STDERR 重定向到管道。以下代码不再出错:
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
}
虽然这解决了眼前的问题,但我不确定究竟是什么导致了它。查看它接受的 CreateProcessW function and the STARTUPINFOW 结构,看起来标准 I/O 重定向是一个全有或全无的选项,由 STARTF_USESTDHANDLES
标志指定。
事实 Python exhibits the same behavior 表明这实际上是 Windows API 或 cmd.exe 的一个特点的实现。
不管怎样,我都没有做任何广泛的研究来弄清楚这里到底发生了什么。
当我尝试通过以下代码启动 cmd.exe
时:
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
}
我想将输出重定向到管道,但它总是报告 The process tried to write to a nonexistent pipe
;当我删除 .stdout(Stdio::piped())
时,没有抛出任何错误。为什么会这样?
EvilTak 的
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
}
虽然这解决了眼前的问题,但我不确定究竟是什么导致了它。查看它接受的 CreateProcessW function and the STARTUPINFOW 结构,看起来标准 I/O 重定向是一个全有或全无的选项,由 STARTF_USESTDHANDLES
标志指定。
事实 Python exhibits the same behavior 表明这实际上是 Windows API 或 cmd.exe 的一个特点的实现。
不管怎样,我都没有做任何广泛的研究来弄清楚这里到底发生了什么。