2015-04-12 8 views
6

मैं अज्ञात स्थिति से पुनर्प्राप्त करने के बाद लाइन पर किसी भी अक्षर को साफ़ करने की कोशिश कर रहा हूं, क्योंकि कुछ मामलों में उनमें प्रॉम्प्ट और अन्य कीवर्ड शामिल हैं जिनका उपयोग मैं भविष्य में कॉल कॉल की अपेक्षा करता हूं। मैंने मिश्रित परिणामों के साथ कई दृष्टिकोणों की कोशिश की है, क्योंकि मैं गैर-अपेक्षित व्यवहार में चल रहा हूं।पायथन pexpect लाइनिंग

देखा अनपेक्षित व्यवहार (अजगर 2.7.9 के साथ pexpect V3.3 उपयोग करते हुए):

  1. निम्नलिखित कोड प्रदर्शन करने के बाद, जब मैं बाद में बफर से पढ़ने की कोशिश, कभी कभी मैं अनियमित व्यवहार जहां केवल देखना एकत्रित पात्रों का हिस्सा साफ़ कर दिया गया था। यह मेरे डाउनस्ट्रीम तर्क पर कहर बरकरार है। मुझे लगता है कि ऐसा इसलिए है क्योंकि पूरा धागा 5 सेकंड तक सो जाता है, इसलिए जब यह जागता है तो इसमें read_nonblocking() कमांड निष्पादित करने से पहले पूर्ण आने वाले बफर को लाने का समय नहीं होता है।

    time.sleep(5) 
    flushedStuff += child.read_nonblocking(100000, timeout=0) 
    
  2. जब मैं एक गैर अवरुद्ध रास्ते में लाइन फ्लश करने के लिए एक .expect कॉल उपयोग करने का प्रयास, मुझे पता चला है कि एक TIMEOUT अपवाद के बाद भेजे बफर में अवरोध है। इसकी सामग्री बच्चे में अपेक्षित के रूप में पाई जा सकती है। संपत्ति से पहले, लेकिन इसे अगले .expect विधि कॉल के दौरान भी पार्स किया जाएगा। तो यह लाइन बिल्कुल फ्लश नहीं करता है! मैंने यह भी देखा कि, read_nonblocking() स्थानीय बफर से नहीं पढ़ता है, लेकिन ओएस के माध्यम से सीधे लाइन से पढ़ता है, इसलिए यह इसे नहीं देखता है।

    try: 
        child.expect("ZzqQJjSh_Impossible_String", timeout = 5) 
    except pexpect.TIMEOUT: 
        pass 
    flushedStuff = child.before 
    

तो यह सब के बाद, मेरे वर्तमान समाधान लाइन फ्लश करने के लिए एक विश्वसनीय तरीका प्रदान करने के लिए अंडे वर्ग का विस्तार करने और एक विधि है जो निम्न है ... जो एक गैर-दस्तावेजी संपत्ति तक पहुँचता करता है जोड़ने के लिए है:

class ExtendedSpawn(pexpect.spawn): 
    def flushBuffer(delay) 
     try: 
      # Greedily read in all the incoming characters 
      self.expect("ZzqQJjSh_Impossible_String", timeout = delay) 
     except pexpect.TIMEOUT: 
      pass 
     # Clear local input buffer inside the spawn Class 
     self.buffer = self.string_type() 
     return self.before 

उपर्युक्त विधि का उपयोग गैर-अवरुद्ध नींद कमांड के लिए भी किया जा सकता है।

ऐसा लगता है कि यह सरल होना चाहिए, यह उल्लेख करने के लिए एक दृष्टिकोण का बहुत जटिल नहीं है, मैंने इसका उल्लेख नहीं किया कि मैंने इसे दो दिन बर्बाद कर दिया। क्या ऐसा करने का कोई बेहतर तरीका है?

धन्यवाद!

उत्तर

0

स्पष्ट pexpect ऐसा करने से बफ़र डेटा तक लगातार पढ़ने के लिए सबसे आसान तरीका उपलब्ध

flushedStuff = '' 
while not child.expect(r'.+', timeout=5): 
    flushedStuff += child.match.group(0) 
0

समस्या को देखने के लिए है, तो आपको निम्न स्क्रिप्ट चला सकते हैं। (ए खोल स्क्रिप्ट संख्या 1 से 10 गूंज होगा, और प्रत्येक संख्या के बाद 1 सेकंड सो pexpect समय समाप्त के लिए 2 सेकंड प्रतीक्षा करें और प्रिंट संख्या देखा होगा।।):

#!/usr/bin/env python 
import pexpect 
child = pexpect.spawn('/bin/sh -c "i=0; while [ $i -lt 10 ]:; do echo $((i=i+1)); sleep 1; done"') 
while True: 
    i=child.expect ([pexpect.TIMEOUT, pexpect.EOF], timeout=2) 
    if i==0: 
     print "before=%s" % child.before 
    else: 
     break 

निर्गम (इस तरह दिखेगा

before='1\r\n2\r\n' 
before='1\r\n2\r\n3\r\n4\r\n' 
before='1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n' 
before='1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n' 
before='1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n' 

समस्या दो पंक्तियों स्क्रिप्ट में जोड़ा जा सकता हल करने के लिए:

#!/usr/bin/env python 
import pexpect 
child = pexpect.spawn('/bin/sh -c "i=0; while [ $i -lt 10 ]:; do echo $((i=i+1)); sleep 1; done"') 
while True: 
    i=child.expect ([pexpect.TIMEOUT, pexpect.EOF], timeout=2) 
    if i==0: 
     print "before=%s" % repr(child.before) 
     if child.before: 
      child.expect (r'.+') 
    else: 
     break 

और उत्पादन की उम्मीद के रूप में हो जाएगा: हम भी संख्या पहले से ही से पहले पढ़ने के लिए) प्राप्त

before='1\r\n2\r\n' 
before='3\r\n4\r\n' 
before='5\r\n6\r\n' 
before='7\r\n8\r\n' 
before='9\r\n10\r\n' 
संबंधित मुद्दे