如何在python上多次输入另一个程序

时间:2016-05-08 11:50:45

标签: python subprocess

我想创建打开两个程序的python文件。这两个程序必须多次相互输入。我打开了两个程序并知道如何为一个程序提供输入,但我不知道如何在一个程序上多次输入并多次输出。我的代码是这样的。

subprocess.call("/usr/bin/gcc -o p1 "+path1,shell=True)
subprocess.call("/usr/bin/gcc -o p2 "+path2,shell=True)
cmd_1 = subprocess.Popen("./p1",shell = True,stdin = subprocess.PIPE,stdout = subprocess.PIPE,stderr = subprocess.PIPE)
cmd_2 = subprocess.Popen("./p2",shell = True,stdin = subprocess.PIPE,stdout = subprocess.PIPE,stderr = subprocess.PIPE)
std_out_1 = cmd_1.stdout
std_out_2 = cmd_2.stdout
for line in std_out_1.readlines():
    print(line.decode('ascii'))
for line in std_out_2.readlines():
    print(line.decode('ascii'))

现在这个程序只是获得程序输出。我想为每个程序提供N次输入并获得N次输出。所以我希望我的代码是这样的。

give_input(n)
for i in range(n):
    t_1 = get_output(t_2) //give input t_2, and get output t_1
    t_2 = get_output(t_1) //give input t_1, and get output t_2

2 个答案:

答案 0 :(得分:0)

通过管道动态交换消息(未经测试):

#!/usr/bin/env python3
from subprocess import Popen, PIPE

with Popen('p1', stdin=PIPE, stdout=PIPE, universal_newlines=True) as p1, \
     Popen('p2', stdin=PIPE, stdout=PIPE, universal_newlines=True) as p2:
    # give_input(n)
    print(n, file=p1.stdin, flush=True)
    print(n, file=p2.stdin, flush=True)
    for i in range(n):
        # t_1 = get_output(t_2) //give input t_2, and get output t_1
        print(p1.stdout.read(1), file=p2.stdin, flush=True)
        # t_2 = get_output(t_1) //give input t_1, and get output t_2
        print(p2.stdout.read(1), file=p1.stdin, flush=True)

它假定子进程期望一行作为请求并返回一个字符作为响应。

使其有效:

  1. p1p2应禁用其内部stdout缓冲(在程序开头调用setvbuf(stdout, NULL, _IONBF, 0);)或在{{1}之后调用fflush() }}。相关:Python C program subprocess hangs at “for line in iter”
  2. printf()p1的目录放入p2或将完整路径$PATH传递到'p1'

答案 1 :(得分:-1)

尝试使用writecommunicate将数据发送到cmd_1cmd_2并获取回复,请参阅https://docs.python.org/3/library/subprocess.html#popen-constructor

for i in range(n):
    cmd_1 = subprocess.Popen("./p1",shell = True,stdin = subprocess.PIPE,stdout = subprocess.PIPE,stderr = subprocess.PIPE)
    cmd_2 = subprocess.Popen("./p2",shell = True,stdin = subprocess.PIPE,stdout = subprocess.PIPE,stderr = subprocess.PIPE)
    cmd_1.stdin.write(cmd_input[n])
    cmd_2.stdin.write(cmd_input[n])
    cmd1_stdout, cmd1_stderr = cmd_1.communicate()
    cmd2_stdout, cmd2_stderr = cmd_2.communicate()
    for line in cmd1_stdout:
        print(line.decode('ascii'))
    for line in cmd2_stdout:
        print(line.decode('ascii'))