How to give input multiple times to another progra

2020-05-01 06:20发布

I want to make python file which opens two programs. This two programs have to get input from each other multiple times. I opened two programs and know how to give input to one program, but i don't know how to give input multiple time on one program and get output multiple time. My code is like this.

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'))

Now this program just get program output. I want to give input N times for each program and get output N times. So I expect my code to be like this.

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条回答
Evening l夕情丶
2楼-- · 2020-05-01 07:03

Try using write and communicate to send data to cmd_1 and cmd_2 and get the response, see 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'))
查看更多
Melony?
3楼-- · 2020-05-01 07:07

To exchange messages via pipes dynamically (not tested):

#!/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)

It assumes that the child processes expect a line as a request and return a single character as a response.

To make it work:

  1. p1, p2 should disable their internal stdout buffering (callsetvbuf(stdout, NULL, _IONBF, 0); at the start of the program) or call fflush() after each printf(). Related: Python C program subprocess hangs at “for line in iter”
  2. Put the directory with p1, p2 into $PATH or pass a full path instead 'p1' into Popen().
查看更多
登录 后发表回答