2012-09-28 45 views
8

प्रसंग:कुछ आदेशों को निष्पादित करने के बाद Pexpect intermittently hanging (EOF का पता नहीं लगा रहा है) क्यों है?

मैं कुछ pexpect का उपयोग करके लिखा कोड, जिनका काम एक कमांड के उत्पादन में दे "लाइव" के लिए है। अर्थात। कमांड पूरा होने तक और इसके आउटपुट के साथ बातचीत करने तक प्रतीक्षा करने के बजाए, जब कोई आदेश कुछ आउटपुट उत्पन्न करता है, या जल्द ही बाद में प्रिंट करता है।

मैं बस एक सेवा शुरू कर रहा हूं और रोक रहा हूं। मैं इस प्रक्रिया ing, और उसके बाद प्रत्येक पंक्ति outputting spawn करके ऐसा कर के रूप में यह छपा है, इसलिए जैसे:

def watch(process): 
    output = "" 
    while True: 
     try: 
      line = process.read_nonblocking(timeout = -1) 
      print(line, end ="") 
      output += line 
     except pexpect.EOF: 
      break 
    del process 
    return output 

while True: 
    print("IN 1") 
    process = pexpect.spawn("service",["zend-server", "stop"], timeout = None) 
    watch(process) 
    print("OUT 1") 

    print("IN 2") 
    process = pexpect.spawn("service",["zend-server", "start"], timeout = None) 
    watch(process) 
    print("OUT 2") 

इस कोड को चाहिए सिर्फ पाश सेवा: इसे शुरू करने और इसे अधिक से अधिक बंद करो, के उत्पादन में मुद्रण शुरुआत के रूप में शुरू/बंद करो। यह आउटपुट ठीक प्रिंट करता है। हालांकि, यह अंततः "आउट 2" से पहले लटकता है। मैं आउटपुट देख सकता हूं, और service कॉल को इसके निष्पादन को रोक सकता हूं। watch फ़ंक्शन कभी भी ईओएफ नहीं उठाता और बाहर निकलता है।

यह प्रत्येक सेवा के साथ नहीं होता है। कुछ सेवाएं लूप अनिश्चित काल तक। zend-server, हालांकि, कुछ अन्य असंबंधित आदेशों के साथ, उसी तरह से अंतःक्रियात्मक रूप से विफल हो जाते हैं।

"आखिरकार लटका" से, मेरा मतलब है कि यह सेवा को कुछ शुरू करता है/प्रत्येक स्टॉप पर चर रोकता है, और लटकता है। यह आम तौर पर 4-6 के बाद मसूड़ों पर होता है, हालांकि पहले कॉल पर कभी नहीं - हमेशा कम से कम दूसरे (इसलिए del कथन; मुझे लगा कि मैं इसे सुरक्षित रखूंगा)।

पायथन 2.6.6, CentOS (64) 6.3, Pexpect 2.3-6, FWIW

प्रश्न:

क्यों pexpect है कुछ आदेश पर लटका? मुझे इस मुद्दे को कैसे हल करना चाहिए? टाइमआउट का उपयोग करना एक व्यवहार्य समाधान नहीं है, क्योंकि इनमें से कुछ आदेश वास्तव में मनमाने ढंग से लंबे समय तक चल सकते हैं। service zend-server stop केवल एक उदाहरण है जिसे मैंने एक उदाहरण के लिए चुना है क्योंकि इसमें अधिक समय नहीं लगता है, और मैं इसे परिष्कृत देख सकता हूं।

मैं क्या कोशिश की है:

मैं निम्नलिखित है, जो expect('\n') का उपयोग करता है के साथ watch विधि की जगह की कोशिश की है, लेकिन परिणाम एक ही कर रहे हैं: पुनरारंभ के परिवर्तनशील है, और फिर एक अंतिम लटका ।

मैं भी सरणी है कि \n के साथ expect एड में pexpect.EOF जोड़ सकते हैं, और लूप से बाहर तोड़ने के लिए भेजे जाने वाले मान को संभालने, यह अभी भी एक ही स्थान पर लटकी हुई है।

def watch2(process): 
    output = "" 
    done = False 
    while True: 
     try: 
      if not process.isalive(): 
       line = process.readline() 
       done = True 
      else: 
       process.expect(['\n']) 
       line = process.before 
      print(line) 
      output += line 
      if done: 
       raise pexpect.EOF(0) 
     except pexpect.EOF: 
      break 
    del process 
    return output 
+1

पर जाकर बफरिंग को अक्षम करने का प्रयास कर सकते हैं जब आप उप-प्रोसेस के साथ कुछ भी इंटरैक्टिव नहीं कर रहे हैं तो आप 'pexpect' का उपयोग क्यों कर रहे हैं? यदि आप केवल आउटपुट में दिलचस्पी रखते हैं तो stdlib से 'subprocess' पर्याप्त होगा। –

+1

यह एक सरल उदाहरण है। उत्पादन संस्करण में, 'उम्मीद' इत्यादि के लिए कॉल हैं, लेकिन मेरे द्वारा सबमिट किए गए छीनने वाले उदाहरण सही तरीके से काम नहीं करते हैं। –

+1

मैं इस कोड का उपयोग कर अपनी समस्या को दोहराना नहीं कर सकता। मुझे यकीन नहीं है कि कोड समस्या है।शायद आपको ज़ेंड सर्वर से कोई आउटपुट नहीं मिल रहा है? – aychedee

उत्तर

2

एक बफरिंग समस्या जहां pexpect अधिक डेटा के लिए इंतज़ार कर रहा है की तरह लग रहा। आप maxread=1 से pexpect.spawn()

+0

कोई प्रभाव नहीं, लेकिन एक अच्छा विचार है! –