我正在Rust中创建一个小的ncurses应用程序,需要与子进程通信.我已经有了一个用Common Lisp编写的原型; 这里的gif 将有希望展示我想做的事情.我正在尝试重写它,因为CL为这么小的工具使用了大量的内存.
我之前没有使用过Rust(或其他低级语言),而且我在弄清楚如何与子进程交互时遇到了一些麻烦.
我目前正在做的大致是这样的:
创建流程:
let mut program = match Command::new(command)
.args(arguments)
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
{
Ok(child) => child,
Err(_) => {
println!("Cannot run program '{}'.", command);
return;
}
};
Run Code Online (Sandbox Code Playgroud)将它传递给无限(直到用户退出)循环,该循环读取并处理输入并像这样监听输出(并将其写入屏幕):
fn listen_for_output(program: &mut Child, output_viewer: &TextViewer) {
match program.stdout {
Some(ref mut out) => {
let mut buf_string = String::new();
match out.read_to_string(&mut buf_string) {
Ok(_) => output_viewer.append_string(buf_string),
Err(_) => return,
};
}
None => return,
};
}
Run Code Online (Sandbox Code Playgroud)read_to_string然而,调用阻止程序直到进程退出.从我所看到的read_to_end,read似乎也阻止.如果我尝试运行类似于ls哪个退出的东西,它可以工作,但是有些东西不能退出, …
这是我试图执行的代码:
fn my_fn(arg1: &Option<Box<i32>>) -> (i32) {
if arg1.is_none() {
return 0;
}
let integer = arg1.unwrap();
*integer
}
fn main() {
let integer = 42;
my_fn(&Some(Box::new(integer)));
}
Run Code Online (Sandbox Code Playgroud)
(在Rust操场上)
我收到以下错误:
error[E0507]: cannot move out of borrowed content
--> src/main.rs:5:19
|
5 | let integer = arg1.unwrap();
| ^^^^ cannot move out of borrowed content
Run Code Online (Sandbox Code Playgroud)
我看到已经有很多关于借阅检查器问题的文档,但在阅读之后,我仍然无法弄清楚问题.
为什么这是一个错误,我该如何解决?
我希望能够使用Rust生成子shell,然后重复传递任意命令并处理它们的输出.我在网上找到了很多例子,告诉我如何传递一个命令并接收它的单个输出,但我似乎无法重复这样做.
例如,以下代码在注释后的行上挂起.(我想可能read_to_string()是阻塞,直到它从子进程收到stdout,但如果是这样,我不明白为什么输出不会...)
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 …Run Code Online (Sandbox Code Playgroud) 我有一个长时间运行的子进程,我需要读取和写入大量数据。我有一个读取器线程和一个写入器线程,分别操作child.stdout和child.stdin:
extern crate scoped_threadpool;
fn main() {
// run the subprocess
let mut child = std::process::Command::new("cat")
.stdin(std::process::Stdio::piped())
.stdout(std::process::Stdio::piped())
.spawn()
.unwrap();
let child_stdout = child.stdout.as_mut().unwrap();
let child_stdin = std::sync::Mutex::new(child.stdin.as_mut().unwrap());
let mut pool = scoped_threadpool::Pool::new(2);
pool.scoped(|scope| {
// read all output from the subprocess
scope.execute(move || {
use std::io::BufRead;
let reader = std::io::BufReader::new(child_stdout);
for line in reader.lines() {
println!("{}", line.unwrap());
}
});
// write to the subprocess
scope.execute(move || {
for a in 0..1000 {
use std::io::Write;
writeln!(&mut …Run Code Online (Sandbox Code Playgroud) 我想收集结构的更改并立即应用它们.基本大纲如下所示:
enum SomeEnum {
Foo,
Bar,
}
struct SomeStruct {
attrib: SomeEnum,
next_attrib: Option<SomeEnum>,
}
impl SomeStruct {
pub fn apply_changes(&mut self) {
if let Some(se) = self.next_attrib {
self.attrib = se;
}
self.next_attrib = None;
}
}
Run Code Online (Sandbox Code Playgroud)
这会产生以下编译器错误:
Run Code Online (Sandbox Code Playgroud)error[E0507]: cannot move out of borrowed content --> src/lib.rs:13:27 | 13 | if let Some(se) = self.next_attrib { | -- ^^^^ cannot move out of borrowed content | | | hint: to prevent move, use `ref se` or `ref mut se` …