通过stdin和stdout与长时间运行的子进程通信

时间:2015-07-04 16:03:28

标签: python c++ ipc stdin child-process

抱歉,我想以前一定会被问过,但出于某种原因,我似乎无法找到答案。

我正在尝试启动一个长时间运行的子进程,例如REPL(lein repl,python),并通过stdin / stdout与它通信。我找到了许多如何在父母只写一次孩子然后读取一些输入的情况下做这个的例子,但是我无法弄清楚如何做到这一点我可以在子进程中编写和读取#39 ; stdin / stdout无限期,就像我使用TCP套接字一样。

理想情况下,我试图在python中执行此操作,但我不介意在C或C ++中查看如何执行此操作。我遇到了一个名为pexpect(https://pexpect.readthedocs.org/en/latest/)的库,它接近我正在寻找的东西,但似乎是为了确保子进程按预期运行或终止对终端的控制到新的过程,而不是双向沟通。我也注意到Python Twisted,但文档有点密集,我仍然无法判断它是否可以做我正在寻找的内容

编辑:这是我现在的一些代码

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'

0 个答案:

没有答案