Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
强制另一个程序';s使用Python取消缓冲的标准输出_Python_Linux_Pipe_Stdout - Fatal编程技术网

强制另一个程序';s使用Python取消缓冲的标准输出

强制另一个程序';s使用Python取消缓冲的标准输出,python,linux,pipe,stdout,Python,Linux,Pipe,Stdout,python脚本控制Linux上的外部应用程序,通过管道将输入传递到外部应用程序stdin,并通过管道从外部应用程序stdout读取输出 问题在于,对管道的写入是按块而不是按行进行缓冲的,因此在控制脚本接收外部应用程序(例如,printf)输出的数据之前会发生延迟 无法更改外部应用程序以添加显式fflush(0)调用 python标准库的模块如何与模块一起使用以实现这一点?尝试使用-u参数运行python解释器: python -u myscript.py 这迫使Python使用无缓冲的std

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

问题在于,对管道的写入是按块而不是按行进行缓冲的,因此在控制脚本接收外部应用程序(例如,printf)输出的数据之前会发生延迟

无法更改外部应用程序以添加显式fflush(0)调用


python标准库的模块如何与模块一起使用以实现这一点?

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

python -u myscript.py

这迫使Python使用无缓冲的stdin/stdout,这可能会对您有所帮助。

我认为这是不可能的。如果源应用程序不刷新其传出缓冲区,则在缓冲区溢出并强制刷新之前,数据不会到达该进程外部

请注意,一个成熟的命令(如)如何有一个选项(-n)使其显式刷新其输出。在从管道读取输入文件名并打印检测到的类型的模式下使用文件时,这是必需的。因为在这种模式下,文件程序完成后不会退出,否则输出不会出现

在较低的级别上考虑这一点:输出缓冲仅仅意味着对缓冲流执行
write()
,将数据复制到内存缓冲区中,直到缓冲区填满,或者(通常)直到找到换行符。然后,将缓冲区中溢出或换行的部分写入底层系统级文件描述符(可以是文件、管道、套接字等)


我不明白你要如何说服程序从外部刷新其缓冲区。

这样做是可能的,但我能想到的唯一解决方案是相当复杂的、不可移植的,并且可能充满了有问题的细节。您可以使用LD_PRELOAD使外部应用程序加载一个动态库,该库包含一个调用setvbuf以取消缓冲stdout的构造函数。您可能还希望在库中包装setvbuf,以防止应用程序显式缓冲自己的标准输出。您需要包装fwrite和printf,以便它们在每次调用时刷新。编写.so预加载将使您脱离python

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

tty的仿真是实现其他流程自动化的一项工作


有一个问题,但我不知道它处理tty仿真的效果如何。

您可以使用PTY通过以下方式解决此问题:

  • 创建pty主/从对
  • 将子进程的stdin、stdout和stderr连接到pty从设备
  • 在家长中向pty主机读写

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


      似乎在解决同样的问题。

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

      谢谢,但问题是受控进程的stdin/stdout的缓冲性质,而不是python脚本。我相信这是可能的(例如)但我想在python脚本本身中实现这一点。@grrussel:据我所知,这两个脚本都处理输入,而不是输出。@grrussel我认为只有当应用程序已经区分以交互方式或批处理方式运行时,这才有效……我相信当stdout是管道或文件时,应用程序使用的libc会将数据逐块写入缓冲区,当它是终端或伪终端时,逐行发送到控制台。libc根据嵌入式应用程序使用哪种文件句柄作为标准输出进行区分,从脚本启动应用程序时可以设置标准输出。但是,当逐行输出更好时,当前使用管道会导致不需要的缓冲。我当前将stdout设置为管道,这会导致逐块缓冲。如果我能够将stdout设置为伪终端,我将获得逐行输出。pexpect似乎可以很好地处理这个问题。我相信它在幕后使用了python pty库。