代码之家  ›  专栏  ›  技术社区  ›  Andrea Ambu

实时获取另一个程序的输出作为输入

  •  11
  • Andrea Ambu  · 技术社区  · 16 年前

    我有两个程序是这样使用的:

    $ c_program | python_program.py
    

    c程序使用以下命令打印内容 printf() python_program.py使用 sys.stdin.readline()

    我想让python_program.py在打印时立即处理c_program的输出,这样它就可以打印自己的当前输出。不幸的是,python_program.py只有在c_proprogram结束后才能获得输入。

    我该如何解决这个问题?

    6 回复  |  直到 16 年前
        1
  •  17
  •   mark4o    16 年前

    #include <stdio.h>
    setvbuf(stdout, NULL, _IOLBF, 0);
    

    #include <stdio.h>
    setlinebuf(stdout);
    

    两者都可以在Linux上运行,但是 setvbuf 是C标准的一部分,因此它将适用于更多的系统。

    默认情况下,stdout将对管道或文件进行块缓冲,或对终端进行行缓冲。由于在这种情况下stdout是一个管道,因此默认设置将是块缓冲。如果它是块缓冲的,那么当缓冲区已满或您调用时,缓冲区将被刷新 fflush(stdout) 。如果它是线路缓冲的,那么它将在每条线路后自动刷新。

        2
  •  8
  •   brianegge    16 年前

    你需要的是让你的C程序在每一行之后调用fflush(stdout)。例如,使用GNU grep工具,您可以调用选项“--line buffered”,这会导致这种行为。看 fflush .

        3
  •  6
  •   Community Mohan Dere    9 年前

    如果你可以修改你的C程序,你已经收到了你的 answer 但我想我会为那些不能/不会修改代码的人提供一个解决方案。

    expect 有一个名为的示例脚本 unbuffer 那就行了。

        4
  •  1
  •   Alex Martelli    16 年前

    你可能想试试 flush 在cpp程序中运行stdout流。

        5
  •  1
  •   Fritz H    16 年前

    据我所知,所有的Unix shell都是通过pty以外的东西实现shell管道的 (通常,他们使用Unix管道!-);因此,C/C++运行库 cpp_program 将知道它的输出不是终端,因此它将缓冲输出(一次缓冲几KB的块)。除非你编写自己的shell(或半准maybeshelloid),通过pyt实现管道,否则我认为使用管道符号无法完成你需要的事情。

    有问题的“shelloid”可能是用Python(或C、Tcl或…)编写的,使用 pty 标准库的模块或基于它的更高级抽象,例如 pexpect ,事实上,通过“基于pty的管道”连接的两个程序是用C++和Python编写的,这一点无关紧要。关键思想是欺骗管道左侧的程序,使其相信其stdout是一个终端(这就是为什么pty必须处于技巧的根源),以欺骗其运行时库不缓冲输出。一旦你编写了这样一个shelloid,你可以用一些语法来调用它,比如:

    当然,通过写作来提供“点解决方案”会更容易 python_program cpp程序 作为一个子进程,AND欺骗它相信它的stdout是一个终端(即。, python程序 然后将直接使用 pexpect shelloid

        6
  •  -1
  •   Abu Aqil    16 年前

    好吧,这听起来可能很愚蠢,但可能会奏效:

    $ c_program >> ./out.log
    

    开发一个从tail命令读取的python程序

    import os
    
    tailoutput = os.popen("tail -n 0 -f ./out.log")
    
    try:
        while 1:
            line = tailoutput.readline()
            if len(line) == 0:
                break
    
            #do the rest of your things here
            print line
    
    except KeyboardInterrupt:
            print "Quitting \n"
    
    推荐文章