[英]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"])
在脚本中,我只是在回应从stdin
到stdout
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.