强制另一个程序的标准输出使用Python无缓冲

python脚本正在控制Linux上的外部应用程序,通过pipe道将input传递到外部应用程序stdin,并通过pipe道从外部应用程序stdout读取输出。

问题在于对pipe道的写入是通过块进行缓冲的,而不是通过线路进行缓冲,因此在控制脚本接收到外部应用程序中的printf输出数据之前发生延迟。

外部应用程序不能被改变来添加显式的fflush(0)调用。

Python标准库的pty模块如何与子stream程模块一起使用来实现这一目标?

Solutions Collecting From Web of "强制另一个程序的标准输出使用Python无缓冲"

这样做是可能的,但我能想到的唯一解决方案是相当复杂的,不可移植的,可能充满了有问题的细节。 您可以使用LD_PRELOAD来使外部应用程序加载一个动态库,其中包含一个调用setvbuf到unbuffer stdout的构造函数。 您可能还想要在库中包装setvbuf以防止应用程序显式缓冲它自己的stdout。 而且你会想要包装fwrite和printf,以便在每次调用时刷新。 写入.so被预加载将带你在python之外。

您可以使用PTYs来解决这个问题:

  • 创建一个pty主/从对;
  • 将子进程的stdin,stdout和stderr连接到pty从设备;
  • 从父母读取和写入父母的主人。

我不认为这是可能的。 如果源应用程序没有刷新其输出缓冲区,则数据将不会超出该进程,直到缓冲区溢出并强制刷新为止。

请注意,诸如文件之类的已建立的命令如何具有一个选项(-n),使其能够显式地清除其输出。 在从管道读取输入文件名的模式下使用文件时,这是必需的,并打印检测到的类型。 由于在这种模式下,文件程序在完成时不会退出,否则输出将不会出现。

考虑到这一点在较低的水平:输出缓冲只是意味着在缓冲流上执行write()将数据复制到内存缓冲区,直到缓冲区填满或(通常)直到找到换行符为止。 然后,直到溢出或换行的缓冲区部分被写入到底层的系统级文件描述符(可能是一个文件,一个管道,一个套接字,…)。

我不明白你怎么说服这个程序从外面冲洗缓冲区。

值得注意的是,有些程序只是在他们认为不会去“真正的用户”(即一个tty)的时候才缓冲他们的输出。 当他们检测到他们的输出正被另一个程序读取时,它们会缓冲。

tty的模拟是Expect在自动化其他进程中所做的一件事情。

Expect有一个纯Python实现 ,但我不知道它如何处理tty仿真。

这个问题的答案可能有所帮助:

Python运行守护进程子进程并读取标准输出

似乎是解决同样的问题。

这个问题有点老了,但我认为你的问题现在可以通过使用子进程来调用你想要执行的命令来调用stdbuf来解决。

尝试使用-u参数运行Python解释器:

 python -u myscript.py 

这迫使Python使用非缓冲的标准输入/标准输出可能会帮助你。