简体   繁体   English

如何从Python实时读取终端输出?

[英]How do I read terminal output in real time from Python?

I am writing a Python program which runs a virtual terminal. 我正在编写一个运行虚拟终端的Python程序。 Currently I am launching it like so: 目前,我正在这样启动它:

import pexpect, thread

def create_input(child, scrollers, textlength=80, height=12):
    while 1:
        newtext = child.readline()
        print newtext

child = pexpect.spawn("bash", timeout=30000)

thread.start_new_thread(create_input,(child))

This works, and I can send commands to it via child.send(command) . 这可行,我可以通过child.send(command)向其发送命令。 However, I only get entire lines as output. 但是,我只得到整行作为输出。 This means that if I launch something like Nano or Links, I don't receive any output until the process has completed. 这意味着如果我启动像Nano或Links这样的东西,在完成该过程之前我不会收到任何输出。 I also can't see what I'm typing until I press enter. 在我按下回车之前,我也无法看到我正在输入的内容。 Is there any way to read the individual characters as bash outputs them? 有什么方法可以读取单个字符作为bash输出它们?

You would need to change the output of whatever program bash is running to be unbuffered instead of line buffering. 您将需要将正在运行的任何程序bash的输出更改为无缓冲,而不是行缓冲。 A good amount of programs have a command line option for unbuffered output. 大量程序具有无缓冲输出的命令行选项。

The expect project has a tool called unbuffer that looks like it can give you all bash output unbuffered. Expect项目有一个名为unbuffer的工具,看起来它可以为您提供所有bash输出无缓冲的功能。 I have personally never used it, but there are other answers here on SO that also recommend it: bash: force exec'd process to have unbuffered stdout 我个人从未使用过它,但是在SO上还有其他建议也推荐它: bash:强制exec进程具有无缓冲的stdout

The problem is lies in something else. 问题出在其他方面。 If you open an interactive shell normally a terminal window is opened that runs bash, sh, csh or whatever. 如果你打开一个交互式shell,通常会打开一个运行bash,sh,csh等的终端窗口。 See the word terminal! 看到单词终端!

In the old days, we connected a terminal to a serial port (telnet does the same but over ip), again the word terminal. 在过去,我们将终端连接到串行端口(telnet的功能与之相同,但通过ip),再次将终端一词。

Even a dumb terminal respond to ESC codes, to report its type and to set the cursor position, colors, clear screen etc. 即使是哑终端也可以响应ESC代码,以报告其类型并设置光标位置,颜色,清晰屏幕等。

So you are starting a subprocess with interactive output, but there is no way in telling that shell and subprocesses are to a terminal in this setup other than with bash startup parameters if there are any. 所以你正在开始一个带有交互式输出的子进程,但除了bash启动参数(如果有的话)之外,没有办法告诉shell和子进程是否在这个设置中的终端。

I suggest you enable telnetd but only on localhost (127.0.0.1) Within your program, make a socket and connect to localhost:telnet and look up how to emulate a proper terminal. 我建议您启用telnetd,但只能在localhost(127.0.0.1)上运行程序,创建套接字并连接到localhost:telnet并查找如何模拟正确的终端。 If a program is in line mode you are fine but if you go to full screen editing, somewhere you will need an array of 80x24 or 132x24 or whatever size you want to store its characters, color. 如果一个程序处于行模式你就可以了,但是如果你进行全屏编辑,你需要一个80x24或132x24的数组,或者你想要存储其字符颜色的任何大小。 You also need to be able to shift lines up in that array. 您还需要能够在该阵列中向上移动行。

I have not looked but I cannot imagine there is no telnet client example in python, and a terminal emu must be there too! 我没有看过,但我无法想象python中没有telnet客户端示例,并且终端e也必须在那里!

Another great thing is that telnet sessions clean up if the the ip connection is lost, eliminating ghost processes. 另一件好事是,如果ip连接丢失,telnet会话将被清除,从而消除了ghost进程。

Martijn 马亭

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

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