2011-11-29 42 views
1

我在写一个运行虚拟终端的Python程序。目前,我启动它,像这样:如何从Python中实时读取终端输出?

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)) 

这工作,我可以通过child.send(command)发送命令给它。但是,我只将整行作为输出。这意味着如果我启动Nano或Links之类的东西,我将不会收到任何输出,直到该过程完成。我也看不到我正在输入的内容,直到我按下回车键。有没有什么方法可以读取单个字符作为bash输出它们?

+0

您需要将输出设置为“无缓冲”,因为此时它显示为“行缓冲”。 – chown

+0

我该怎么做? – Skyler

回答

1

问题是在于别的东西。如果您通常打开交互式shell,会打开一个运行bash,sh,csh或其他任何操作的终端窗口。看到终端这个词!

在过去,我们连一个终端到串行端口(远程登录不相同,但IP电话),又字终端。

即使是一个哑终端来响应ESC代码,报告类型和设置光标位置,颜色,画面清晰等

所以,你开始用交互输出的子进程,但也没有办法在告诉shell和子进程对于这个设置中的终端而不是bash启动参数(如果有的话)。

我建议你启用telnetd,但只在本地主机上(1​​27.0.0.1) 在你的程序中,建立一个套接字并连接到localhost:telnet并查找如何模拟一个合适的终端。如果一个程序处于行模式,那么你很好,但如果你进行全屏编辑,那么你需要一个80x24或132x24的数组,或者你想要存储其字符和颜色的任何大小的数组。您还需要能够在该阵列中切换阵容。

我没有看过,但我不能想象没有telnet客户端例如Python和终端动车组必须在那里呢!

另一个伟大的事情是,telnet会话清理,如果IP连接丢失,消除重过程。

Martijn

+0

这可能是一个适合您需求的灵感: http://antony.lesuisse.org/software/ajaxterm/ Martijn – Martijn

2

你需要改变任何程序bash的运行是无缓冲,而不是行缓冲的输出。很多程序都有一个非缓冲输出的命令行选项。

expect项目有一个名为unbuffer的工具,它看起来像它可以给你所有的bash输出无缓冲。我个人从来没有使用它,但也有其他的答案在这里,也推荐它:bash: force exec'd process to have unbuffered stdout

+0

这工作除了不纳米,链接,vi等。Vi告诉我:'Vim:警告:输出不是终端。' – Skyler

+0

@ user677624嗯,我知道有一种方法来排序“假”是一个终端所以它可以与vi/nano/etc一起工作...我会尝试再次找到并包含它。 – chown

+0

@ user677624我读了一些使用'os.system'而不是'pexpect.spawn'来表示会使Vim有用的东西,但我无法证实这一点。我会尽力找到更具体的东西。 – chown