从Python中读取终端

问题描述:

如何从Python中的终端接收输入?从Python中读取终端

我正在使用Python与另一个生成用户输入输出的程序进行交互。 我使用subprocess.Popen()来输入到程序,但我不能将stdout设置为subprocess.PIPE,因为程序似乎没有刷新过,所以一切都卡在缓冲区中。 该程序的标准输出似乎是打印到终端,我看到输出时,我不重定向标准输出。但是,我需要Python来读取和解释现在在终端中的输出。

对不起,如果这是一个愚蠢的问题,但我似乎无法得到这个工作。

+0

如果程序需要交互式输入/输出,请尝试pexpect:http://www.noah.org/wiki/Pexpect。如果没有,使用subprocess.PIPE并调用'myprocess.communicate()'应该可以工作。 – 2011-06-15 17:42:59

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

http://docs.python.org/library/subprocess.html#using-the-subprocess-module

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

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

其次,我认为下一个最简单的,考虑使用具有使用虚拟终端或pty(我认为是“伪电传”)设施的Twisted框架与您的子进程交谈。但是,这可能会影响应用程序的设计(可能会更好,但这可能不适用于您)。 http://twistedmatrix.com/documents/current/core/howto/process.html

如果上述两个选项都不适用于您,那么您可以减少为自己解决坚韧不拔的I/O并发问题。第三,尝试使用fcntl()和O_NONBLOCK设置你的管道(所有的,在fork()之前)到非阻塞模式。然后,您可以在尝试读取/写入之前使用select()来测试读/写的准备情况;但是您仍然需要捕获IOError并测试EAGAIN,因为即使在这种情况下它也可能发生。这可能取决于子进程的行为,允许您在尝试读取数据之前等待数据真正显示。

最后的手段是自己实现PTY逻辑。如果你看过termio选项,ioctl()调用等的引用,那么这就是你所反对的。我之前没有这样做过,因为它很复杂,我从来没有真正需要。如果这是你的命运,祝你好运。