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
我需要在 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