繁体   English   中英

从Python终端读取

[英]Read from the terminal in Python

如何使用Python从终端接收输入?

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

抱歉,如果这是一个愚蠢的问题,但我似乎无法解决这个问题。

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

首先,也是最简单的,您可以一次从管道读取一个字节。 这就是我所说的“脏乱”,它会降低性能,但是很简单,它可以确保您的read()调用仅在第一个字节进入之前才阻塞,而不是等待缓冲区填满永远不会填满。 但是,这不会强制其他进程刷新其写缓冲区,因此,如果这是问题所在,那么该方法将无济于事。

其次,我认为最简单的方法是考虑使用Twisted框架,该框架具有使用虚拟终端或pty(我认为是“ pseudo-teletype”)与您的子进程对话的功能。 但是,这可能会影响应用程序的设计(可能会更好),但无论如何,这可能都不适合您。 http://twistedmatrix.com/documents/current/core/howto/process.html

如果以上两种方法都不适合您,那么您将不得不自己解决棘手的I / O并发问题。

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

最后的办法是自己实现PTY逻辑。 如果您看到过诸如termio选项,ioctl()调用等之类的内容的引用,那么您将要面对。 我以前没有做过这件事,因为它很复杂,而且我从未真正需要这样做。 如果这是您的命运,请祝您好运。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM