簡體   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