我有以下Rust代码,它通过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行: header ,接下来的5行
来自stdin和页脚。
read_line
中的for x in v.into_iter()
仅读取5行并且rust进程终止,从而在python端触发了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))
关于python - 与Python子进程通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60312198/