2013-06-09 28 views
5

Tôi đang cố gắng tương tác với chương trình NCURSES.Làm cách nào để tôi tương tác với quy trình con giả vờ là thiết bị đầu cuối?

Ví dụ tôi đang sử dụng Màn hình GNU và chạy aptitude bên trong. (bạn có thể dùng thử với mc thay thế.)

Chương trình bên dưới bắt đầu phiên màn hình với -x để kết nối với phiên của tôi.

Tôi muốn điều hướng bằng cách nhấn Mũi tên xuống và Mũi tên lên.

Nếu tôi gửi 'q' để thoát, tôi thấy một hộp bật lên trong phiên màn hình khác của tôi.

Tôi cần làm gì để nhận các phím đặc biệt như phím mũi tên hoạt động?

Dường như nó bỏ qua chuỗi VT102 mà tôi đang gửi.

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

CẬP NHẬT:

  1. Ted nói với tôi đi bộ trong lịch sử lệnh với ESC [A (lên) và ESC [B (xuống) làm việc với bash.

  2. Tự hỏi tại sao trong aptitude nó không thay đổi TERM = xterm thành TERM = ansi sửa lỗi. Tại sao xterm không làm việc vẫn còn đố tôi.

+0

Đây là câu hỏi hơi khó hiểu - bạn có hỏi cách gửi các phím điều khiển, chẳng hạn như Mũi tên xuống, trên mạng qua Xoắn không? – Michael

+0

Không phải trên mạng. spawnProcess bắt đầu một quá trình cục bộ và nối các mô tả tập tin để bạn có thể nói chuyện với nó. –

+0

ESC B trong 'foo' có nghĩa là mũi tên xuống không? Mũi tên xuống tạo ESC [B, không chỉ ESC B. – torek

Trả lời

2

Tôi đã thay đổi TERM = xterm thành TERM = ansi để sửa lỗi. Tại sao xterm không công việc vẫn còn câu đố tôi.

Sử dụng Ubuntu 13.04, có vẻ như các mã kiểm soát ansixterm là không hoàn toàn giống nhau.

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

... do đó, có vẻ như bạn cần gửi chuỗi '\033OB' để mô phỏng một mũi tên xuống với xterm.

Các mã sau đây làm việc cho tôi ...

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 

... mặc dù nó hơi say lên thiết bị đầu cuối của tôi sau khi hoàn thành, vì vậy tôi đã phải làm ...

$ stty sane 

... để làm cho nó hoạt động trở lại.


Cập nhật

Chỉ cần tìm thấy những gì có thể là một cách dễ dàng hơn để xác định mã số kiểm soát chính xác. Nếu bạn tải vi, hãy chuyển sang chế độ chèn, sau đó nhấn CTRL-V theo sau là khóa bạn muốn mô phỏng, nó hiển thị chuỗi ký tự được gửi từ thiết bị đầu cuối.

Ví dụ ...

Down Arrow: ^[OB 

Page Up: ^[[5~ 

... nơi ^[CTRL-[, ví dụ: '\033'.

2

Một phương pháp tốt để lấy mã cho các chức năng đầu cuối cụ thể là sử dụng lệnh tput, đối với một số loại thiết bị đầu cuối cụ thể với tùy chọn -T.

Trong Python, sử dụng các mô-đun curses để có được mã số chính xác:

from curses import * 
setupterm('xterm') 

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

Bạn có thể đọc về khả năng có sẵn bằng cách tung ra man terminfo. Ví dụ trên có thể cần savetty() trước setuptermresetty() sau khi bạn lấy mã khóa mà bạn quan tâm. Nếu không, thiết bị đầu cuối của bạn có thể bị giữ ở trạng thái xấu. Trong C, cũng tốt khi có một số trình xử lý thoát, để thiết lập lại thiết bị đầu cuối do lỗi, nhưng mô-đun Python có thể xử lý nó theo cách riêng của nó.

Phương pháp này, trái ngược với thể xác định rõ mã số thiết bị đầu cuối, có lợi thế là cầm tay giữa các hệ thống, nơi terminfo cho xterm có thể khác so với trên bản phân phối Linux hiện hành.

0

Có lẽ cái gì đó như Pexpect có thể bằng cách hữu ích ở đây:

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

Its a thực hiện python của Expect, mà về cơ bản đồng hồ đầu vào và dựa trên các mẫu thực hiện những hành động như thể một người đang ngồi ở đó tương tác với các ứng dụng .

+0

Tôi nên có một cái nhìn gần hơn về pexpect. Tôi quan tâm đến các mẫu theo dõi trong mã vt102. Bây giờ tôi đang viết mẫu phù hợp với riêng tôi, nhưng tôi muốn được quan tâm để xem liệu tôi có thể sử dụng pexpect bằng cách nào đó không. –

Các vấn đề liên quan