简体   繁体   English

无需冲洗()和换行即可在子流程输出上进行非阻塞读取

[英]Non-blocking read on subprocess output without flush() and new line

I have a program that I can't modify. 我有一个无法修改的程序。 This program print data to stdout WITHOUT flushing it or put \\n inside and wait for input and so on. 该程序将数据打印到stdout无需冲洗它或将\\n放入其中并等待输入等。

My question is how can I, from a Python script, print in real-time stdout and write into his stdin ? 我的问题是,如何从Python脚本中实时打印stdout并写入其stdin I found some ways to write into his stdin without closing the programs but the problem remains for printing his stdout too. 我找到了一些无需关闭程序即可写入他的stdin方法,但是打印他的stdout仍然存在问题。

In fact, there are some issues with thread, Popen and fcntl to print in real time his output but they all assumes that the program flush stdout after each print and include \\n in their output. 实际上,线程, Popenfcntl存在一些问题,无法实时打印其输出,但它们都假定程序在每次打印后刷新stdout ,并在输出中包含\\n

To be clear, let's say I have a program test.c : 为了清楚test.c ,假设我有一个程序test.c

#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;
}

How can I, from a Python script, output the first fprintf() then writing answer into his stdin and so on in the same way I could simply launch test.c ? 我如何从Python脚本中输出第一个fprintf()然后将答案写入他的stdin中,依此类推,就像我可以简单地启动test.c

The purpose is to control data sent to this program from a script and still having return on what happens. 目的是控制从脚本发送到该程序的数据,并且仍然可以返回发生的情况。

You may use the following program which is heavily relying on the subprocess package from the standard Python language: 您可以使用以下程序,该程序在很大程度上依赖于标准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)

So, the program you just wrote in C would give the following: 因此,您刚刚用C编写的程序将提供以下内容:

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

Note that you cannot avoid the \\n character simply because it is used by your target program to know that you send the answer to a question. 请注意,您不能仅仅因为目标程序使用\\n字符就知道您已将问题的答案发送给了\\n字符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM