我如何与冒充终端的子进程交互?

2024-10-05 14:32:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我想和一个NCURSES项目互动。在

作为一个例子,我使用GNU屏幕并在里面运行aptitude。(你可以用mc代替它。)

下面的程序用-x启动一个屏幕会话以连接到我的会话。在

我想按箭头向下和箭头向上导航。在

如果我发送'q'退出我看到一个框弹出在我的另一个屏幕会话。在

我需要做些什么才能让像箭头键这样的特殊键工作?在

它目前似乎忽略了我发送的VT102序列。在

from twisted.internet import protocol, reactor

class MyPP(protocol.ProcessProtocol):
    def connectionMade(self):
        reactor.callLater(1.0, self.foo)

    def foo(self):
        self.transport.write('\033[B')

    def processExited(self, reason):
        print "processExited, status %s" % (reason.value.exitCode,)

    def outReceived(self, data):
        print data

    def errReceived(self, data):
        print "errReceived!", data

pp = MyPP()
command = ['screen', '-x']
reactor.spawnProcess(pp, command[0], command, {'TERM':'xterm'}, usePTY=True)

reactor.run()

更新

  1. 泰德告诉我在命令历史中使用ESC[A(向上)和ESC[B(向下)与bash一起工作。

  2. 想知道为什么在aptitude中,我没有把TERM=xterm改成TERM=ansi,这样就可以修复它了。为什么xterm不起作用我还是很困惑。


Tags: selfdata屏幕foodef箭头protocolcommand
3条回答

也许像Pexpect这样的东西在这里可能有用:

https://pypi.python.org/pypi/pexpect

它是Expect的一个python实现,它基本上监视输入并基于模式执行操作,就像一个人坐在那里与应用程序交互一样。在

I've changed TERM=xterm to TERM=ansi which fixes it. Why xterm doesn't work still puzzles me.

使用Ubuntu13.04,看起来ansi和{}的控制代码并不完全相同。在

$ infocmp ansi | grep cud
        cr=^M, cub=\E[%p1%dD, cub1=\E[D, cud=\E[%p1%dB, cud1=\E[B,
        kcud1=\E[B, kcuf1=\E[C, kcuu1=\E[A, khome=\E[H, kich1=\E[L,

$ infocmp xterm | grep cud
        cud=\E[%p1%dB, cud1=^J, cuf=\E[%p1%dC, cuf1=\E[C,
        kcub1=\EOD, kcud1=\EOB, kcuf1=\EOC, kcuu1=\EOA,

…所以看起来您需要发送字符串'\033OB'来模拟带有xterm的下箭头。在

下面的代码对我有用。。。在

^{pr2}$

……虽然完工后把我的终端搞砸了,所以我不得不。。。在

$ stty sane

…让它重新工作。在


更新

刚刚找到了一种更容易确定正确控制代码的方法。如果加载vi,进入插入模式,然后按CTRL-V,然后按要模拟的键,它将显示从终端发送的文本字符串。在

例如。。。在

Down Arrow: ^[OB

Page Up: ^[[5~

…其中^[CTRL-[,即'\033'。在

获得特定终端函数代码的一个好方法是使用tput命令,对于某些带有-T选项的特定终端类型。在

在Python中,使用curses模块获得正确的代码:

from curses import *
setupterm('xterm')

key_up = tigetstr("kcuul")
key_down = tigetstr("kcudl")

您可以通过启动man terminfo来了解可用功能。上面的例子可能需要savetty()setupterm之前,和{}之后。否则,您的终端可能会处于一个状态。在C语言中,在某些退出处理程序中也有这样的功能,以便在出错时重置终端,但Python模块可以自己处理。在

与硬编码终端代码相比,这种方法具有在系统之间可移植的优点,其中extermterminfo可能不同于当前Linux发行版。在

相关问题 更多 >