我如何与伪装成终端的子进程交互? [英] How do I interact with a child process pretending to be a terminal?

查看:21
本文介绍了我如何与伪装成终端的子进程交互?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试与NCURSES程序交互。

作为一个例子,我使用GNU Screen并在里面运行apitty。(您可以改用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('33[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. Ted告诉我在命令历史中使用Esc[A(Up)和Esc[B(Down)与bash一起工作。

  2. 想知道为什么在智能方面不是这样,我已经将Term=xTerm更改为Term=ansi,这就解决了它。我仍然不明白为什么xTerm不起作用。

推荐答案

我已将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,

...所以看起来您需要发送字符串'33OB'来使用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('33OB') # arrow down
time.sleep(1)
p.stdin.write('33OB') # arrow down
time.sleep(1)
p.stdin.write('33OA') # arrow up
time.sleep(1)
p.stdin.write('33OA') # arrow up
time.sleep(1)
p.stdin.write('q')      # quit
time.sleep(1)
p.stdin.write('y')      # confirm

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

$ stty sane

...以使其再次工作。


更新

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

例如...

Down Arrow: ^[OB

Page Up: ^[[5~

...其中^[CTRL-[,即'33'

这篇关于我如何与伪装成终端的子进程交互?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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