用Python从终端读取数据

用Python从终端读取数据,python,terminal,Python,Terminal,如何在Python中接收来自终端的输入 我正在使用Python与另一个从用户输入生成输出的程序接口。 我正在使用subprocess.Popen()向程序输入,但我无法将stdout设置为subprocess.PIPE,因为程序似乎从未刷新过,所以所有内容都会卡在缓冲区中。 程序的标准输出似乎是打印到终端,当我不重定向stdout时,我会看到输出。但是,我需要Python来读取和解释现在在终端中的输出 如果这是一个愚蠢的问题,很抱歉,但我似乎无法让它工作。您是否尝试过将Popen对象中的bufs

如何在Python中接收来自终端的输入

我正在使用Python与另一个从用户输入生成输出的程序接口。 我正在使用subprocess.Popen()向程序输入,但我无法将stdout设置为subprocess.PIPE,因为程序似乎从未刷新过,所以所有内容都会卡在缓冲区中。 程序的标准输出似乎是打印到终端,当我不重定向stdout时,我会看到输出。但是,我需要Python来读取和解释现在在终端中的输出


如果这是一个愚蠢的问题,很抱歉,但我似乎无法让它工作。

您是否尝试过将
Popen
对象中的
bufsize
设置为
0
?我不确定是否可以强制缓冲区与接收大小分离,但我会尝试


您是否尝试将
Popen
对象中的
bufsize
设置为
0
?我不确定是否可以强制缓冲区与接收大小分离,但我会尝试


子进程中的缓冲是一个常见问题。这里有四种可能的方法

首先,也是最简单的,您可以从管道中一次读取一个字节。这就是我所说的“肮脏攻击”,它会带来性能损失,但这很简单,它保证read()调用只会阻塞到第一个字节,而不是等待一个永远不会填满的缓冲区填满。但是,这不会强制另一个进程刷新其写缓冲区,因此,如果这是一个问题,那么这种方法无论如何也不会帮助您

第二,我认为下一步最简单,考虑使用具有虚拟终端功能的扭曲框架,或者PTY(“伪电传”)来与您的子进程对话。但是,这可能会影响应用程序的设计(可能会更好,但无论如何,这可能不在您的考虑范围之内)

如果以上两个选项都不适合您,那么您就只能自己解决棘手的I/O并发问题

第三,尝试使用带有O_NONBLOCK的fcntl()将管道(所有管道,在fork()之前)设置为非阻塞模式。然后,在尝试读/写之前,可以使用select()测试读/写准备情况;但您仍然必须捕获IOError并测试EAGAIN,因为即使在这种情况下,它也可能发生。根据子进程的行为,这可能允许您在尝试读入数据之前等待数据真正显示出来


最后的手段是自己实现PTY逻辑。如果您看到过对诸如termio选项、ioctl()调用等内容的引用,那么这就是您面临的问题。我以前没有做过,因为这很复杂,我从来没有真正需要做过。如果这就是你的命运,祝你好运。

子进程中的缓冲是一个常见问题。这里有四种可能的方法

首先,也是最简单的,您可以从管道中一次读取一个字节。这就是我所说的“肮脏攻击”,它会带来性能损失,但这很简单,它保证read()调用只会阻塞到第一个字节,而不是等待一个永远不会填满的缓冲区填满。但是,这不会强制另一个进程刷新其写缓冲区,因此,如果这是一个问题,那么这种方法无论如何也不会帮助您

第二,我认为下一步最简单,考虑使用具有虚拟终端功能的扭曲框架,或者PTY(“伪电传”)来与您的子进程对话。但是,这可能会影响应用程序的设计(可能会更好,但无论如何,这可能不在您的考虑范围之内)

如果以上两个选项都不适合您,那么您就只能自己解决棘手的I/O并发问题

第三,尝试使用带有O_NONBLOCK的fcntl()将管道(所有管道,在fork()之前)设置为非阻塞模式。然后,在尝试读/写之前,可以使用select()测试读/写准备情况;但您仍然必须捕获IOError并测试EAGAIN,因为即使在这种情况下,它也可能发生。根据子进程的行为,这可能允许您在尝试读入数据之前等待数据真正显示出来


最后的手段是自己实现PTY逻辑。如果您看到过对诸如termio选项、ioctl()调用等内容的引用,那么这就是您面临的问题。我以前没有做过,因为这很复杂,我从来没有真正需要做过。如果这是您的命运,祝您好运。

如果程序需要交互式输入/输出,请尝试Pexect:。如果没有,使用subprocess.PIPE并调用
myprocess.communicate()
应该可以工作。如果程序需要交互式输入/输出,请尝试pexpect:。如果没有,使用subprocess.PIPE并调用
myprocess.communicate()
应该可以。