如何与假装成终端的子进程进行交互?

Edd*_*onk 5 python twisted

我正在尝试与NCURSES计划进行互动.

作为一个例子,我使用GNU Screen并在内部运行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()
Run Code Online (Sandbox Code Playgroud)

更新:

  1. 泰德告诉我,走在与ESC [A(上)和ESC [B(下)使用bash工作的命令历史记录.

  2. 奇怪,为什么性向不我已经改变TERM = xterm中以TERM = ANSI其修复它.为什么xterm不起作用仍困扰着我.

Aya*_*Aya 2

我已将 TERM=xterm 更改为 TERM=ansi 修复了该问题。为什么 xterm 不起作用仍然让我困惑。

使用Ubuntu 13.04,看起来ansixterm控制代码不太一样。

$ 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,
Run Code Online (Sandbox Code Playgroud)

...所以看起来您需要发送字符串'\033OB'来模拟向下箭头xterm

以下代码对我有用......

import subprocess
import os
import time

# Set TERM=xterm in case it isn't already
os.environ['TERM'] = 'xterm'

# Spawn aptitude
p = subprocess.Popen('aptitude', stdin=subprocess.PIPE)

# Wait for a bit to let it load from cache
time.sleep(5)

# Control it using xterm control codes
p.stdin.write('\033OB') # arrow down
time.sleep(1)
p.stdin.write('\033OB') # arrow down
time.sleep(1)
p.stdin.write('\033OA') # arrow up
time.sleep(1)
p.stdin.write('\033OA') # arrow up
time.sleep(1)
p.stdin.write('q')      # quit
time.sleep(1)
p.stdin.write('y')      # confirm
Run Code Online (Sandbox Code Playgroud)

...尽管完成后它搞砸了我的终端,所以我不得不做...

$ stty sane
Run Code Online (Sandbox Code Playgroud)

...让它再次工作。


更新

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

例如...

Down Arrow: ^[OB

Page Up: ^[[5~
Run Code Online (Sandbox Code Playgroud)

...^[在哪里CTRL-[,即'\033'