【问题标题】:Popen.communicate\stdin.write stuckPopen.communicate\stdin.write 卡住
【发布时间】:2015-04-22 15:22:56
【问题描述】:

我使用的是 python 版本 2.7.9,当我尝试从 Popen 进程中读取一行时,它一直卡住,直到进程结束。如何在 stdin 结束之前读取它?

如果输入是“8200”(正确的密码),那么它会打印输出。 但是如果密码从'8200'改成没有输出,为什么?

子流程源码:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    char password[10];
    int num;
    do
    {
        printf("Enter the password:");
        scanf("%s", &password);

        num = atoi(password);

        if (num == 8200)
            printf("Yes!\n");
        else
            printf("Nope!\n");
    } while (num != 8200);

    return 0;
}

Python 源码:

from subprocess import Popen, PIPE

proc = Popen("Project2", shell=True, stdin=PIPE,stdout=PIPE,stderr=PIPE)
#stdout_data = proc.communicate(input='8200\r\n')[0]
proc.stdin.write('123\r\n')
print proc.stdout.readline()

【问题讨论】:

    标签: communicate


    【解决方案1】:

    如果您将 printf 更改为

    printf("Enter the password:\n");
    

    并添加冲洗

    fflush (stdout);
    

    缓冲区被刷新。刷新意味着即使缓冲区尚未满,也会写入数据。我们需要添加一个 \n 来强制换行,因为 python 将缓冲所有输入,直到它读取一个 \n in

    proc.stdout.readline();
    

    在python中我们添加了一个readline。然后看起来像这样:

    proc = Popen("Project2", shell=True, stdin=PIPE,stdout=PIPE,stderr=PIPE)
    proc.stdout.readline()
    proc.stdin.write('123\r\n')
    print proc.stdout.readline()
    

    这就是正在发生的事情:

    1. python 运行子进程
    2. 子进程写“输入密码:\n”
    3. python 读取“输入密码:”这一行,然后什么也不做
    4. python 将“123”写入子进程
    5. 子进程读取 123
    6. 子进程将检查 123 是否为 8200,这是错误的,并会回答“否!”
    7. “不!”由 python 读取并使用最后一行代码打印到标准输出

    【讨论】:

    • 请尝试添加 fflush(stdout);在 printf 之后
    • 是的,我们正朝着这个方向前进……但现在的输出是:'输入密码:'我希望它打印出来:“是的!”或“不!” (我添加了 fflush (stdout);仅在第一个 printf 之后)
    • 您可以使用 fprintf (stderr, "Enter password") 将输入密码打印到 std err;是和不是机智 fprintf (stdout, "Yes");
    • 我无法更改子流程的源代码。。现在只是一个练习,我想附加到另一个软件,所以我不想进行这样的更改。
    • 那你是怎么添加 fflush 的呢?无论如何,你可以在 python 中读取一行而不用它做任何事情。例如 proc.stdin.write 之前的 'proc.stdout.readline()'
    猜你喜欢
    • 2014-02-04
    • 2019-03-23
    • 2015-07-19
    • 2013-02-26
    • 2017-12-29
    • 2011-08-04
    • 2011-11-17
    • 2014-03-22
    • 1970-01-01
    相关资源
    最近更新 更多