相关疑难解决方法(0)

如何在不阻塞Rust的情况下读取子进程的输出?

我正在Rust中创建一个小的ncurses应用程序,需要与子进程通信.我已经有了一个用Common Lisp编写的原型; 这里的gif 将有希望展示我想做的事情.我正在尝试重写它,因为CL为这么小的工具使用了大量的内存.

我之前没有使用过Rust(或其他低级语言),而且我在弄清楚如何与子进程交互时遇到了一些麻烦.

我目前正在做的大致是这样的:

  1. 创建流程:

    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)
  2. 将它传递给无限(直到用户退出)循环,该循环读取并处理输入并像这样监听输出(并将其写入屏幕):

    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哪个退出的东西,它可以工作,但是有些东西不能退出, …

io process blocking pty rust

14
推荐指数
2
解决办法
2987
查看次数

展开时无法摆脱借来的内容

这是我试图执行的代码:

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 borrow-checker

13
推荐指数
1
解决办法
6698
查看次数

无法多次向生成的子进程进行管道传输

我希望能够使用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)

command pipe process rust borrow-checker

11
推荐指数
1
解决办法
1045
查看次数

读取和写入长时间运行的 std::process::Child

我有一个长时间运行的子进程,我需要读取和写入大量数据。我有一个读取器线程和一个写入器线程,分别操作child.stdoutchild.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)

rust

6
推荐指数
1
解决办法
2217
查看次数

如何移出作为选项的struct字段?

我想收集结构的更改并立即应用它们.基本大纲如下所示:

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)

这会产生以下编译器错误:

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` …
Run Code Online (Sandbox Code Playgroud)

copy rust borrow-checker

6
推荐指数
1
解决办法
723
查看次数

标签 统计

rust ×5

borrow-checker ×3

process ×2

blocking ×1

command ×1

copy ×1

io ×1

pipe ×1

pty ×1