2013-06-09 4 views
5

मैं एक एनसीयूआरएसईएस कार्यक्रम के साथ बातचीत करने की कोशिश कर रहा हूं।टर्मिनल होने का नाटक करने वाले बच्चे की प्रक्रिया से मैं कैसे बातचीत करूं?

उदाहरण के तौर पर मैं जीएनयू स्क्रीन का उपयोग कर रहा हूं और अंदर योग्यता चला रहा हूं। (आप इसके बजाय एमसी के साथ कोशिश कर सकते हैं।)

नीचे दिया गया प्रोग्राम मेरे सत्र से कनेक्ट करने के लिए एक स्क्रीन सत्र शुरू करता है।

मैं तीर-डाउन और तीर-अप दबाकर नेविगेट करना चाहता हूं।

अगर मैं बाहर निकलने के लिए 'q' भेजता हूं तो मुझे अपने अन्य स्क्रीन सत्र में एक बॉक्स पॉप अप दिखाई देता है।

तीर कुंजी जैसे विशेष कुंजी प्राप्त करने के लिए मुझे क्या करने की ज़रूरत है?

वर्तमान में यह वीटी 102 अनुक्रम को अनदेखा कर रहा है जो मैं भेज रहा हूं।

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 [एक (ऊपर) और ESC [बी (नीचे) बैश के साथ काम करता साथ आदेश इतिहास में चलने को कहा।

  2. आश्चर्य की बात क्यों है कि मैंने टीईआरएम = xterm को TERM = ansi में बदल दिया है जो इसे ठीक करता है। क्यों xterm काम नहीं करता है अभी भी मुझे पहेली।

+0

यह एक कुछ भ्रामक सवाल है - आप कह रहे हैं कि कैसे मुड़ के ऊपर इस तरह के तीर से नीचे के रूप में नियंत्रण चाबियाँ, भेजने के लिए, नेटवर्क के पार? – Michael

+0

नेटवर्क भर में नहीं। spawnProcess स्थानीय रूप से एक प्रक्रिया शुरू करता है और फ़ाइल वर्णनकर्ताओं को तार देता है ताकि आप इससे बात कर सकें। –

+0

में 'foo' नीचे-तीर होना ESC बी है? नीचे-तीर उत्पन्न ESC [बी, न सिर्फ ESC बी – torek

उत्तर

2

मैं अवधि = एएनएसआई जो इसे ठीक करता है करने के लिए अवधि = टर्म बदल दिया है। क्यों xterm काम अभी भी मुझे पहेली करता है।

उबंटू 13.04 का उपयोग करना, ऐसा लगता है कि ansi और xterm नियंत्रण कोड काफी ही नहीं हैं।

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

... इसलिए जैसे आप xterm के साथ एक नीचे तीर का अनुकरण करने की स्ट्रिंग '\033OB' भेजने की जरूरत है यह लग रहा है।

निम्नलिखित कोड मेरे लिए काम करता ...

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 

... हालांकि यह पूरा होने के बाद मेरी टर्मिनल बँधा हुआ है, तो मैं नहीं था ...

$ stty sane 

... इसे फिर से काम करने के लिए।


अद्यतन

बस पाया क्या सही नियंत्रण कोड निर्धारित करने के लिए एक आसान तरीका हो सकता है। यदि आप vi लोड करते हैं, तो सम्मिलित मोड में जाएं, फिर CTRL-V दबाएं जिसके बाद आप अनुकरण करना चाहते हैं, यह टर्मिनल से भेजे गए शाब्दिक स्ट्रिंग को दिखाता है।

उदाहरण के लिए ...

Down Arrow: ^[OB 

Page Up: ^[[5~ 

... जहां ^[CTRL-[ है, यानि कि '\033'

2

विशेष टर्मिनल फ़ंक्शंस के लिए कोड प्राप्त करने के लिए एक अच्छी विधि tput कमांड का उपयोग कर रही है, कुछ विशेष टर्मिनल प्रकार के लिए -T विकल्प के साथ।

अजगर में, सही कोड प्राप्त करने के लिए curses मॉड्यूल का उपयोग:

from curses import * 
setupterm('xterm') 

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

आप man terminfo के लॉन्च के साथ उपलब्ध क्षमताओं के बारे में पढ़ सकते हैं। उपरोक्त उदाहरण setupterm से पहले savetty() और resetty() आवश्यकता हो सकती है जब आप कुंजी कोड आप में रुचि रखते हैं प्राप्त करने के बाद। अन्यथा, अपने टर्मिनल एक बुरा राज्य में छोड़ा जा सकता है। सी में यह है कि कुछ बाहर निकलने के हैंडलर में है करने के लिए और साथ ही, त्रुटि पर टर्मिनल रीसेट करने के लिए अच्छा था, लेकिन पायथन मॉड्यूल अपनी ही में है कि संभाल सकता है।

इस विधि, इसके विपरीत टर्मिनल कोड हार्डकोड करने के लिए, सिस्टम, जहां terminfo के लिए टर्म कि मौजूदा लिनक्स वितरण पर से भिन्न हो सकता के बीच पोर्टेबल होने का लाभ है।

0

शायद Pexpect की तरह कुछ यहाँ उपयोगी द्वारा कर सकता है:

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

इसकी अपेक्षा, जो मूल रूप से इनपुट देखता है और पैटर्न पर आधारित का एक अजगर कार्यान्वयन करता है कार्रवाई के रूप में अगर एक व्यक्ति वहाँ बैठा हुआ था एप्लिकेशन के साथ सहभागिता ।

+0

मुझे pexpect पर एक नज़र डालना चाहिए। मैं vt102 कोड में पैटर्न की निगरानी में रुचि रखते हैं। अब मैं अपना खुद का पैटर्न मिलान कर रहा हूं, लेकिन मुझे यह देखने में दिलचस्पी होगी कि क्या मैं किसी भी तरह pexpect का उपयोग कर सकता हूं। –

संबंधित मुद्दे