繁体   English   中英

与 Python 子进程通信

[英]Communicate with Python subprocess

我有以下 Rust 代码,它通过stdin将字符串发送到子stdin并读取来自它的stdout

use std::io::{BufRead, BufReader, Write};
use std::process::{Command, Stdio};
fn main() {
   let mut child = Command::new("cat")
        .stdin(Stdio::piped())
        .stdout(Stdio::piped())
        .spawn()
        .expect("Did not run");
    let v = vec!["11111", "2222222", "3333", "end", "soooooooooooooooo"];
    let k = child.stdin.as_mut().unwrap();
    let mut g = BufReader::new(child.stdout.as_mut().unwrap());
    for x in v.into_iter() {
        k.write_all(x.as_bytes()).unwrap();
        k.write_all("\n".as_bytes()).unwrap();
        let mut s: String = String::new();
        g.read_line(&mut s).unwrap();
        println!("{}", s)
    }
}

该示例运行没有问题,但是当我尝试使用 python 脚本执行相同操作时,它失败了。

要调用脚本,我正在像这样创建child

    let mut child = Command::new("c:\\Windows\\py.exe")
        .args(&["-u", "echo.py"])

在脚本中,我只是在回应从stdinstdout

import sys
import time
if __name__=="__main__":
    fo=sys.stdout
    fo.write('python starts at: %.0f\n'%(time.time()*1000))
    line = sys.stdin.readline()
    while True:
        fo.write(line+"\n")
        line = sys.stdin.readline()
    fo.write('python ends at: %.0f\n'%(time.time()*1000))

我得到的输出是:

python starts at: 1582166542281                                                                

11111                                                                                          



2222222                                                                                        



Traceback (most recent call last):                                                             
  File "c:\Users\asia\Documents\projects\python\echo.py", line 8, in <module>                  
    fo.write(line+"\n")                                                                        
OSError: [Errno 22] Invalid argument                                                           

我的看法是管道在打印第二个字符串附近的某个地方断裂,但我不知道为什么。 我在这里缺少什么?

提前致谢

Rust 进程在 python 进程的 stdin 上写了 5 行,正是这些字符串来自:

let v = vec!["11111", "2222222", "3333", "end", "soooooooooooooooo"];

但是在 python 方面,你试图写回 rust 7 行:一个标题,5 行来自 stdin 和一个页脚。

read_line内部for x in v.into_iter()只读取5行和防锈处理终止时,触发BrokenPipe在具有写两行蟒侧。

我认为还需要一些控制来退出 python 端的while True循环。

沿着这些路线的东西,只是为了得到这个想法:

use std::io::{BufRead, BufReader, Write};
use std::process::{Command, Stdio};
fn main() {
   let mut child = Command::new("python").args(&["-u", "echo.py"])
        .stdin(Stdio::piped())
        .stdout(Stdio::piped())
        .spawn()
        .expect("Did not run");
    let v = vec!["11111", "2222222", "3333", "end", "soooooooooooooooo"];
    let k = child.stdin.as_mut().unwrap();
    let mut g = BufReader::new(child.stdout.as_mut().unwrap());

    // read the header "python starts at ..."
    let mut s: String = String::new();
    g.read_line(&mut s).unwrap();
    println!("{}", s);

    for x in v.into_iter() {
        k.write_all(x.as_bytes()).unwrap();
        k.write_all("\n".as_bytes()).unwrap();
        let mut s: String = String::new();

        // read len(v) lines, in this case 5 lines
        g.read_line(&mut s).unwrap();
        println!("{}", s)
    }

    // Something is neeeded to signal termination of input
    // assume for this example a zero length string
    k.write_all("\n".as_bytes()).unwrap();

    // read the empty string and the footer "python ends at ..."
    let mut s: String = String::new();
    g.read_line(&mut s).unwrap();
    g.read_line(&mut s).unwrap();
    println!("{}", s);
}

Python:

import sys
import time

if __name__ == "__main__":
    fo = sys.stdout
    fo.write('python starts at: %.0f\n' % (time.time()*1000))
    line = sys.stdin.readline()
    while True:
        fo.write(line)
        line = sys.stdin.readline()
        if (line == "\n"):
            break

    fo.write('python ends at: %.0f\n' % (time.time()*1000))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM