Rust 您如何将流程的输出流化?
我相信我大体上理解这样做的一种方式:Rust 您如何将流程的输出流化?,rust,Rust,我相信我大体上理解这样做的一种方式: 创建一个命令 使用Stdio::piped()创建一对新的输出流 配置command.stdout()和command.stderr() 产生过程 创建一个新线程并将stderr和stdout传递给它 我很乐意接受任何生成长时间运行的进程并通过任何方式将输出流式传输到控制台的例子 听起来你想要: 虽然公认的答案是正确的,但它并不涵盖非琐碎的情况 要流式输出并手动处理,请使用Stdio::piped()并手动处理调用spawn返回的子级上的.stdout属性
- 创建一个
命令
- 使用
创建一对新的输出流Stdio::piped()
- 配置
和command.stdout()
command.stderr()
- 产生过程
- 创建一个新线程并将stderr和stdout传递给它
我很乐意接受任何生成长时间运行的进程并通过任何方式将输出流式传输到控制台的例子 听起来你想要:
虽然公认的答案是正确的,但它并不涵盖非琐碎的情况 要流式输出并手动处理,请使用
并手动处理调用Stdio::piped()
返回的子级上的spawn
属性,如下所示:.stdout
use std::process::{Command, Stdio}; use std::path::Path; use std::io::{BufReader, BufRead}; pub fn exec_stream<P: AsRef<Path>>(binary: P, args: Vec<&'static str>) { let mut cmd = Command::new(binary.as_ref()) .args(&args) .stdout(Stdio::piped()) .spawn() .unwrap(); { let stdout = cmd.stdout.as_mut().unwrap(); let stdout_reader = BufReader::new(stdout); let stdout_lines = stdout_reader.lines(); for line in stdout_lines { println!("Read: {:?}", line); } } cmd.wait().unwrap(); } #[test] fn test_long_running_process() { exec_stream("findstr", vec!("/s", "sql", "C:\\tmp\\*")); }
使用std::process:{Command,Stdio}; 使用std::path::path; 使用std::io::{BufReader,BufRead};
pub fn exec_stream(binary:P,args:vec)一般来说,为了给对话提供一个起点,OP(您)最好至少提供一个显示问题的代码示例,然后询问如何解决所述问题。例如,您可以切换“一种方式”在代码示例中。我很乐意接受任何生成长时间运行的进程和流式输出到控制台的示例。这实际上与默认行为不同吗?@msgmaxim您可以查看默认行为:继承stdin/stdout/stderr for
或spawn
,但为rstatus
.TL;DR:不,我不这么认为。有时只是过于明确或将文档读回OP就足够了。注意原始问题上的评论,要求MCVE,试图让OP进一步解释问题。'\_(ツ)_/''避免了我在调试中浪费更多的时间。谢谢!这是如何将stdout/stderr流式传输到控制台的简单解决方案,以及如何正确地向用户提出stdin问题。这个答案非常有用!快速提问:流式读取部分被放在单独的作用域中有什么特殊原因吗?@PascalPrecht分离output
的可变借词,首先在cmd
中,第二个在stdout
中。今天,编译器将在cmd.wait()
语句,但我认为在过去情况并非如此。因此这里的范围需要限制cmd.wait()之前自动删除
stdout
的生存期。stdout
use std::process::{Command, Stdio}; fn main() { let mut cmd = Command::new("cat") .args(&["/usr/share/dict/web2"]) .stdout(Stdio::inherit()) .stderr(Stdio::inherit()) .spawn() .unwrap(); // It's streaming here let status = cmd.wait(); println!("Exited with status {:?}", status); }
use std::process::{Command, Stdio}; use std::path::Path; use std::io::{BufReader, BufRead}; pub fn exec_stream<P: AsRef<Path>>(binary: P, args: Vec<&'static str>) { let mut cmd = Command::new(binary.as_ref()) .args(&args) .stdout(Stdio::piped()) .spawn() .unwrap(); { let stdout = cmd.stdout.as_mut().unwrap(); let stdout_reader = BufReader::new(stdout); let stdout_lines = stdout_reader.lines(); for line in stdout_lines { println!("Read: {:?}", line); } } cmd.wait().unwrap(); } #[test] fn test_long_running_process() { exec_stream("findstr", vec!("/s", "sql", "C:\\tmp\\*")); }