Python 子进程输入被读取两次

Python subprocess input is read twice

我需要在 python 中包装一个程序并将其输入并打印输出。但是,如果它给它一行输入,它似乎会使用它作为输入,直到程序终止。我用 C 编写了一个非常基本的程序(称为 inout),它接受两行输入并打印到标准输出。

from subprocess import Popen, PIPE, STDOUT

p = Popen(['inout'], stdout=PIPE, stdin=PIPE, stderr=STDOUT)
out, err = p.communicate(input=b'Why is this twice')

print(out)
print("done")

这个程序的输出是:

b'Why is this twice\r\nWhy is this twice\r\n'
done

我怎样才能阻止这种情况发生?

这个bug实际上是在你的C++程序中;它为它的两个打印重新使用 in 变量,这意味着如果对 getline 的第二次调用没有 return 任何东西(并且它在你的情况下没有,因为stdin 的 EOF 在第一次 getline 调用后到达),第一个 getline 调用编辑的内容 return 将被打印两次,因为它们仍然保存在 in 中.如果您稍微调整 C++ 程序以在对 getline:

的两次调用之间重置 in,这是显而易见的
#include <iostream>
using namespace std;

int main()
{
 string in; 
 getline(cin, in); 
 cout << in << endl; 
 in = ""; // reset in
 getline(cin, in); 
 cout << in << endl;
 return 0;
}

输出:

b'Why is this twice'


done

编辑:

根据您在评论中提出的要求,您想要这样的东西:

from subprocess import Popen, PIPE, STDOUT

p = Popen(['./inout'], stdout=PIPE, stdin=PIPE, stderr=STDOUT, bufsize=0)  # bufsize=0 keeps stdout from being buffered.

# Send first line to inout
p.stdin.write(b'Why is this twice\n') 

# Read first line out output
first = p.stdout.readline()
print("got {}".format(first))

# Get line from user
a = input()

# Send second line to inout
p.stdin.write('{}\n'.format(a).encode('utf-8')) 

# Read second line from inout
second = p.stdout.readline()
print('also got {}'.format(second))

p.wait()
print("done")

输出:

got b'Why is this twice\n'
sdf  # This was typed by me
b'sdf\n'
done