Tokio(我使用的是0.2,期货是0.3)具有process::Command.output()
,它在完成后从子进程返回组合输出(stdout和stderr)。但是,出于某些原因,我想流输出:
它可能大于可用内存。
stdout和stderr输出可能是交错的(我意识到,一般而言,两者之间的关系不会成为可以依赖的东西,但是我宁愿付出尽可能多的努力来保持结果类似于正常运行该过程。
我不想等到进程终止后才开始返回输出。
我尝试将select!
与一对期货和一个循环一起使用:
let outbuf = [0u8; 512];
let errbuf = [0u8; 512];
let outfut = child_stdout.read(&mut outbuf).fuse();
let errfut = child_stderr.read(&mut errbuf).fuse();
pin_mut!(outfut, errfut);
loop {
select! {
result = outfut => {
let length = result?;
if length != 0 {
output.write_all(&outbuf[..length]).await?
outfut.set(child_stdout.read(&mut outbuf).fuse())
}
}
result = errfut => {
let length = result?;
if length != 0 {
output.write_all(&errbuf[..length]).await?
errfut.set(child_stderr.read(&mut errbuf).fuse())
}
}
complete => break
}
}
let status = child.await?
当然,这是行不通的,因为我两次借用了缓冲区;我尝试过以各种方式重新排列代码,但是当使用select!
时,我似乎总是不得不两次借用东西。 (还要注意,实际上,if
语句中的输出比我上面显示的要多,并且stdout和stderr分支彼此不同,因此您不能仅将stdout和stderr都重定向到同一地点,并称之为一天。)
很显然,这不是正确的方法。是否有一种惯用的Rust方法来实现我所追求的目标?