我希望能够使用 Rust 生成一个子 shell,然后反复向它传递任意命令并处理它们的输出。我在网上找到了很多示例,向我展示了如何传递单个命令并接收其单个输出,但我似乎无法重复执行此操作。
例如,以下代码挂在注释后的行上。(我想可能read_to_string()
会阻塞,直到它从子进程接收到标准输出,但如果是这样,我不明白为什么该输出不会出现......)
let mut child_shell = match Command::new("/bin/bash")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
{
Err(why) => panic!("couldn't spawn child_shell: {}", Error::description(&why)),
Ok(process) => process,
};
loop {
{
match child_shell.stdin.as_mut().unwrap().write("ls".as_bytes()) {
Err(why) => panic!(
"couldn't send command to child shell: {}",
Error::description(&why)
),
Ok(_) => println!("sent command to child shell"),
}
}
{
let mut s = String::new();
// ↓ hangs on this line ↓
match child_shell.stdout.as_mut().unwrap().read_to_string(&mut s) {
Err(why) => panic!("couldn't read bash stdout: {}", Error::description(&why)),
Ok(_) => print!("bash responded with:\n{}", s),
}
}
}
我是 Rust 的初学者,我认为问题在于我对借用检查器/引用规则的理解有限,因为如果我从代码中删除循环指令并将引用更改为,上述运行良好(对于单次迭代)结构的内部是std::process::Child
不可变的;例如从这个:
child_shell.stdin.as_mut().unwrap().write("ls".as_bytes())
对此:
child_shell.stdin.unwrap().write("ls".as_bytes())
显然,重复运行ls
不是我的最终目标,我知道我可以只编写一个 shell 脚本,然后让 Rust 重复运行它——但是(除了学习更多关于 Rust 的目标!)这是我需要做的事情至少在原则上能够为一个更复杂的项目做(如果它可能证明与任何解决方案相关,我很乐意进入,但这可能超出了这个问题的范围!)
最后,如果事实证明不可能以这种方式使用子 shell,我仍然想学习如何重复/连续地管道进出运行其他任意命令的衍生进程,就像我一样无法在 Rust 文档、教程或 Stack Overflow 上找到任何信息。