即时获取另一个程序的输出作为input

我有两个程序,我用这种方式:

$ c_program | python_program.py 

c_program使用printf()和python_program.py使用sys.stdin.readline()读取数据,

我想使python_program.py进程c_program的输出,因为它立即打印,以便它可以打印自己的当前输出。 不幸的是python_program.py只有在c_program结束之后才能获得input。

我该如何解决这个问题?

Solutions Collecting From Web of "即时获取另一个程序的输出作为input"

只需将stdout设置为在C程序的开头进行行缓冲(在执行任何输出之前),如下所示:

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

要么

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

任何一个都可以在Linux上工作,但是setvbuf是C标准的一部分,所以它可以在更多的系统上工作。

默认情况下,标准输出将被阻塞缓冲管道或文件,或线路缓冲的终端。 由于stdout在这种情况下是一个管道,所以默认情况下会被阻塞。 如果是块缓冲,那么当缓冲区满了或者调用fflush(stdout)时,缓冲区将被刷新。 如果是行缓冲,那么每行之后会自动刷新。

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

如果你可以修改你的C程序,你已经收到你的答案,但我想我会包括那些不能/不会修改代码的解决方案。

期望有一个名为unbuffer的示例脚本,可以做到这一点。

所有的Unix shell(我知道)都是通过别的东西来实现shell管道的(比如通常使用Unix管道)。 因此, cpp_program的C / C ++运行时库将知道它的输出不是一个终端,因此它将缓冲输出(一次以几KB为单位)。 除非你编写自己的shell(或semiquasimaybeshelloid)通过pyt来实现管道,否则我相信没有办法用流水线符号来做你所需要的。

所讨论的“shelloid”可能是用Python(或者C,或者Tcl,或者…)编写的,使用标准库的pty模块或者基于它的更高级的抽象,例如pexpect ,通过“基于pty的管道”连接的两个程序是用C ++编写的,而Python是非常不相关的。 关键的想法是欺骗程序到管道的左侧,相信它的标准输出是一个终端(这就是为什么一个pty必须在这个技巧的根源)来愚弄它的运行时库到NOT缓冲输出。 一旦你写了这样一个shelloid,你可以用下面的语法来调用它:

$ shelloid'cpp_program | python_program.py”

当然,通过编写python_program知道它必须产生cpp_program作为一个子进程,并欺骗它相信它的stdout是一个终端(也就是说, python_program会直接使用pexpect ,for例)。 但是,如果你有一百万个这样的情况,你想打破由系统提供的C运行时库执行的正常缓冲,或者你想重用现有过滤器的许多情况下,编写shelloid可能实际上是更好的。

您可能想要尝试在cpp程序中flush stdout流。

确定这可能听起来很愚蠢,但它可能工作:

输出你的PGM到一个文件

 $ 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"