对不起,我想这之前已经被问过,但由于某种原因我似乎无法找到答案 .
我试图启动一个长时间运行的子进程,如REPL(lein repl,python),并通过stdin / stdout与它通信 . 我找到了许多如何在父母只写一次孩子然后读取一些输入的情况下做这个的例子,但是我无法弄清楚如何做到这一点我可以写入和读取子进程'stdin / stdout无限期,就像我使用TCP套接字一样 .
理想情况下我试图在python中执行此操作,但我不介意在C或C中看到如何执行此操作 . 我遇到了一个叫做pexpect(https://pexpect.readthedocs.org/en/latest/)的图书馆,它接近我所说的是否可以做我正在寻找的东西
编辑:这是我现在的一些代码
from subprocess import Popen, PIPE
p = Popen('lein repl 1>&2', shell=True, stderr=PIPE)
# p.communicate('(print "Hello, world!")')[0]
for line in iter(p.stderr.readline, b''):
print('my-repl>> ' + line)
# p.stderr.flush()
print 'End of script'
此代码将启动该程序并允许我直接与它进行交互 . 当我添加stdin = PIPE时,程序会冻结 . 如果我添加stdin = PIPE并尝试调用p.communicate我会收到错误
ValueError: I/O operation on closed file
编辑2:一些工作代码 . 它读取10行(启动时由nREPL输出的当前数字),然后写入一行,然后读取两行 .
来自子进程导入Popen,PIPE
# Whether to use stdout or stderr as the output stream
# for the child process
proc_use_stderr = False
# Process Variables
p = None
p_out = None
p_in = None
# Config
nrepl_num_start_lines = 11
if proc_use_stderr:
p = Popen('lein repl 1>&2', shell=True, stderr=PIPE, stdin=PIPE)
p_out = p.stderr
else:
p = Popen(['lein', 'repl'], stdout=PIPE, stdin=PIPE)
p_out = p.stdout
p_in = p.stdin
child_output_lines = []
for i in range(0, nrepl_num_start_lines):
child_output_lines.append(p_out.readline().strip('\n'))
# Leads to: ValueError: I/O operation on closed file
# p.communicate('(print "Hello, repl!")\n')[0]
p_in.write('(print "Hello, repl!")\n')
p_in.flush()
print 'Starting readline'
child_output_lines.append(p_out.readline().strip('\n'))
child_output_lines.append(p_out.readline().strip('\n'))
print 'Ending readline'
for i in range(0, len(child_output_lines)):
print i, ':', child_output_lines[i]
# TODO: Terminal gets all goofy after the process exits
# p.stderr.flush()
# p.stderr.close()
p_out.flush()
p_out.close()
p_in.flush()
p_in.close()
p.terminate()
print 'Summary:'
print 'Num Received Lines:', len(child_output_lines)
print 'Line List:', child_output_lines
print 'End of script'