2013-06-09 17 views
5

Bir NCURSES programıyla etkileşime geçmeye çalışıyorum. Örneğin, GNU Ekranını kullanıyorum ve içinde koşulu çalıştırıyorum. (bunun yerine mc ile deneyebilirsiniz.)Terminal gibi davranan bir alt işlemle nasıl etkileşime girerim?

Aşağıdaki program, oturumuma bağlanmak için -x ile bir ekran oturumu başlatır.

Ok aşağı ve Yukarı ok tuşlarına basarak gitmek istiyorum.

Çıkmak için 'q' gönderirsem, diğer ekran oturumumda bir kutu görüyorum.

Ok tuşları gibi özel anahtarlar almak için ne yapmam gerekir?

Şu anda gönderdiğim VT102 dizisini görmezden geliyor gibi görünüyor.

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

GÜNCELLEME:

  1. Ted ESC [A (yukarı) ve ESC [B (aşağı) bash ile çalışır ile komut geçmişi yürüyüş söyledi.

  2. Neden yetenekte olduğumu merak etme TERM = xterm değerini TERM = ansi olarak değiştirdim. Neden xterm çalışmıyor?

+0

Bu biraz kafa karıştırıcı bir sorudur - Twisted üzerinden ağ üzerinden Ok aşağı gibi kontrol tuşlarının nasıl gönderileceğini mi soruyorsunuz? – Michael

+0

Ağ genelinde değil. spawnProcess bir süreci yerel olarak başlatır ve dosya tanımlayıcılarını bağlar, böylece onunla konuşabilirsiniz. –

+0

"foo" daki ESC B aşağı ok muydu? Aşağı ok ESC üretir [B, sadece ESC B değil. – torek

cevap

2

bunu düzeltir SÜRE = ansi TERM = xterm değiştirdik. Neden xterm çalışmıyor? ansi ve xterm kontrol kodları oldukça aynı değildir gibi

Ubuntu 13.04 kullanma görünüyor.

$ 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, 

... yani xterm ile aşağı oku taklit dize '\033OB' göndermek gerekir gibi görünüyor. o tamamlanmasından sonra benim terminali berbat, bu yüzden yapmak zorunda olsa

Aşağıdaki kod

... ... ... benim için

$ stty sane 

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 

çalışır ... tekrar çalışmak için.


Güncelleme Sadece doğru kontrol kodlarını belirlemek için daha kolay bir yolu ne olabileceğini gördük. vi'u yüklerseniz, ekleme moduna geçin, ardından CTRL-V tuşlarına basın ve ardından taklit etmek istediğiniz anahtarla, terminalden gönderilen değişmez diziyi gösterir.

Örneğin ...^[CTRL-[ olduğunu

Down Arrow: ^[OB 

Page Up: ^[[5~ 

... yani '\033'.

2

Belirli terminal işlevleri için kodları elde etmek için iyi bir yöntem, -T seçeneğiyle bazı belirli terminal türleri için tput komutunu kullanıyor. Python

doğru kodlarını almak için curses modülü kullanmak:

from curses import * 
setupterm('xterm') 

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

Sen man terminfo başlatarak mevcut yetenekleri hakkında okuyabilirsiniz. Yukarıdaki örnek, ilgilendiğiniz anahtar kodlarını aldıktan sonrave resetty()'dan önce savetty()'a ihtiyaç duyabilir. Aksi takdirde, terminaliniz hatalı durumunda kalabilir. C de, bazı çıkış işleyicilerinde, hata durumunda terminali sıfırlamak iyi oldu, ancak Python modülü bunu kendi başına halledebilir.

Bu yöntem, uç kodları kodlamak aksine, xterm için terminfo'ya Linux dağıtımında daha farklı olabilir sistemleri arasında taşınabilir olma avantajına sahiptir.

0

Belki pexpect gibi bir şey yararlı burada tarafından şurada olabilir:

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

bir kişinin uygulama ile etkileşim orada oturuyordu sanki temelde modellerine dayalı girişi izler ve hangi Expect bir piton uygulama eylemleri gerçekleştirir Onun .

+0

Pexpect'e daha yakından bakmalıyım. Vt102 kodlarındaki kalıpları izlemekle ilgileniyorum. Şimdi kendi desen eşleştirmeyi yazıyorum, ama bir şekilde pexpect'i kullanıp kullanamayacağımı görmek isterim. –

İlgili konular