在没有flush()和新行的子进程输出上进行非阻塞读取

时间:2018-03-02 15:02:17

标签: python subprocess stdout stdin nonblocking

我有一个我无法修改的程序。此程序将数据打印到stdout而不会将其刷新或将\n置于内部并等待输入等等。

我的问题是,我如何从Python脚本中实时打印stdout并写入他的stdin?我发现了一些方法可以在不关闭程序的情况下写入stdin,但问题仍然是打印他的stdout

事实上,线程Popenfcntl存在一些问题,需要实时打印输出,但它们都假定每次打印后程序刷新stdout并包含{ {1}}在他们的输出中。

要说清楚,假设我有一个程序\n

test.c

我怎样才能从Python脚本输出第一个#include <stdio.h> #include <stdlib.h> #include <string.h> int main (void) { char name[100], age[100], location[100]; fprintf (stdout, "\nWhat is your name : "); fgets (name, sizeof (name), stdin); name[strcspn (name, "\n")] = '\0'; fprintf (stdout, "How old are you : "); fgets (age, sizeof (age), stdin); age[strcspn (age, "\n")] = '\0'; fprintf (stdout, "Where do you live : "); fgets (location, sizeof (location), stdin); location[strcspn (location, "\n")] = '\0'; fprintf (stdout, "\nHello %s, you have %s years old and live in %s\n\n", name, age, location); return 0; } ,然后将答案写入他的标准输入等,就像我只需启动fprintf()一样?

目的是控制从脚本发送到此程序的数据,并且仍然可以返回发生的事情。

1 个答案:

答案 0 :(得分:0)

您可以使用以下程序,该程序严重依赖于标准Python语言中的subprocess包:

def run_program(cmd, sinput=''):
    """Run the command line and output (ret, sout, serr)."""
    import subprocess

    proc =  subprocess.Popen(cmd,
                             stdin=subprocess.PIPE,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
    sin = proc.stdin
    sout, serr = proc.communicate(sinput.encode("utf-8"))
    ret = proc.wait()

    return (ret, sout, serr)

因此,您刚用C编写的程序将提供以下内容:

cmd = ['myprogram']
sinput = 'myname\n6\nWhitechapel\n'
(ret, sout, serr) = run_program(cmd, sinput)

请注意,您无法避免使用\n字符,因为目标程序会使用该字符来确定您是否发送问题的答案。