在 Python 中从终端读取 [英] Read from the terminal in Python

查看:40
本文介绍了在 Python 中从终端读取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How can I receive input from the terminal in Python?

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

I am using Python to interface with another program which generates output from user input. I am using subprocess.Popen() to input to the program, but I can't set stdout to subprocess.PIPE because the program does not seem to flush ever, so everything gets stuck in the buffer. The program's standard output seems to be to print to terminal, and I see output when I do not redirect stdout. However, I need Python to read and interpret the output which is now in the terminal.

对不起,如果这是一个愚蠢的问题,但我似乎无法让它起作用.

Sorry if this is a stupid question, but I can't seem to get this to work.

推荐答案

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

Buffering in child processes is a common problem. Here are four possible approaches.

首先,也是最简单的,您可以一次从管道中读取一个字节.这就是我所说的肮脏的黑客",它会带来性能损失,但它很容易,并且它保证您的 read() 调用只会阻塞直到第一个字节进入,而不是等待缓冲区填满永远不会填满.但是,这不会强制其他进程刷新其写入缓冲区,因此如果这是问题所在,此方法无论如何都无济于事.

First, and easiest, you could read one byte at a time from your pipe. This is what I would call a "dirty hack" and it carries a performance penalty, but it's easy and it guarantees that your read() calls will only block until the first byte comes in, rather than wait for a buffer to fill up that's never going to fill up. However, this does not force the other process to flush its write buffer, so if that is the issue this approach will not help you anyway.

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

Second, and I think next-easiest, consider using the Twisted framework which has a facility for using a virtual terminal, or pty ("pseudo-teletype" I think) to talk to your child process. However, this can affect the design of your application (possibly for the better, but this may not be in the cards for you regardless). http://twistedmatrix.com/documents/current/core/howto/process.html

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

If neither of the above options works for you, you're reduced to solving gritty I/O concurrency issues yourself.

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

Third, try setting your pipes (all of them, before fork()) to non-blocking mode using fcntl() with O_NONBLOCK. Then you can use select() to test for read/write readiness before trying the read/write; but you still have to catch IOError and test for EAGAIN because it can happen even in this case. This may, depending on the behavior of the child process, allow you to wait until the data really shows up before trying to read it in.

最后的办法是自己实现 PTY 逻辑.如果您已经看到对诸如 termio 选项、ioctl() 调用等内容的引用,那么这就是您所反对的.我以前没有这样做过,因为它很复杂,我从来没有真正需要这样做.如果这是你的命运,祝你好运.

The last resort is to implement the PTY logic yourself. If you've seen references to stuff like termio options, ioctl() calls, etc. then that's what you're up against. I have not done this before, because it's complicated and I have never really needed to. If this is your destiny, good luck.

这篇关于在 Python 中从终端读取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆