处理子流程的标准输入和标准输出

时间:2019-08-24 17:57:03

标签: python subprocess

我想编写一个Python脚本,该脚本创建一个子进程,从stdout读取并写入stdin。向stdin写入的内容应取决于从stdout读取的内容。

我已经尝试了很多有关subprocess.Popen的东西,但没有任何解决方法。

基本上,我想编写一个脚本,使以下c代码打印“成功”:

#include <stdio.h>
#include <stlib.h>
int main()
{
    int var, inp;
    for (int i = 0; i < 100; i++) {
        var = rand();
        printf("Please type %d:\n", var); //random var. is printed
        scanf("%d", &inp);                //inp == var?

        if (inp != var) {
            printf("you failed miserably\n");
            return 0;
        }
    }

    printf("success\n");
    return 0;
}

我无法从stdout读取数据,但仍保持子进程活动。任务似乎很简单,但是我找不到简单的解决方案。

我希望可以使用的Python代码:

from subprocess import *
def getNum(s):  # "Please type 1234567:\t" -> "1234567"
    return "".join([t for t in s if t.isdigit()])

p = Popen("./io", stdin=PIPE, stdout=PIPE) #io is the binary obtained from above c code
for i in range(100):
    out = p.stdout.readline() #script deadlocks here
    print( out )
    inp = getNum(out)+"\n"#convert out into desired inp
    p.stdin.write(inp)
print (p.communicate()[0]) #kill p and get last output

这种方法可能有点天真,但是我也不明白为什么它不起作用。

1 个答案:

答案 0 :(得分:1)

python程序被困,等待从stdout接收内容。这可能是由于stdout缓冲造成的。可能有几种方法可以更改此行为,但是一种快速的测试方法是更改​​C可执行文件以在打印出随机生成的数字后立即强制fflush。 C代码如下所示:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int var, inp;
    for (int i = 0; i < 100; i++) {
        var = rand();
        printf("Please type %d:\n", var); //random var. is printed

        // ADDED EXPLICIT stdout flush
        fflush(stdout);

        scanf("%d", &inp);                //inp == var?

        if (inp != var) {
            printf("you failed miserably\n");
            return 0;
        }
    }

    printf("success\n");
    return 0;
}

有了这一更改,原始的python脚本就能够推动整个交互。