2009-02-09 12 views
21

चल रहा है यह मेरा उपप्रक्रिया है:एक उपप्रक्रिया की stdout को बाधित करना, जबकि यह

import time, sys 
for i in range(200): 
    sys.stdout.write('reading %i\n'%i) 
    time.sleep(.02) 

और यह नियंत्रित करने और उपप्रक्रिया के उत्पादन को संशोधित स्क्रिप्ट है:

import subprocess, time, sys 

print 'starting' 

proc = subprocess.Popen(
    'c:/test_apps/testcr.py', 
    shell=True, 
    stdin=subprocess.PIPE, 
    stdout=subprocess.PIPE ) 

print 'process created' 

while True: 
    #next_line = proc.communicate()[0] 
    next_line = proc.stdout.readline() 
    if next_line == '' and proc.poll() != None: 
     break 
    sys.stdout.write(next_line) 
    sys.stdout.flush() 

print 'done' 

क्यों readline और है communicate प्रक्रिया पूरी होने तक प्रतीक्षा कर रही है? क्या उपप्रोसेस 'स्टडआउट रीयल-टाइम पास (और संशोधित) करने का कोई आसान तरीका है?

बीटीडब्ल्यू, मैंने this देखा है, लेकिन मुझे लॉगिंग सुविधाओं की आवश्यकता नहीं है (और इसे अधिक समझने की परेशानी नहीं है)।

मैं विंडोज एक्सपी पर हूं।

+0

संबंधित:

मैं निम्नलिखित कोड, ActiveState पर कुछ पदों से प्रेरित इस्तेमाल किया [? अजगर प्रिंट के उत्पादन में फ्लश करने के लिए कैसे] (http://stackoverflow.com/q/230751/95735) –

उत्तर

14

जैसा चार्ल्स ने पहले ही उल्लेख किया है, समस्या बफरिंग है। मैं एसएनएमपीडी के लिए कुछ मॉड्यूल लिखते समय भी इसी तरह की समस्या में भाग गया, और इसे ऑटो-फ्लशिंग संस्करण के साथ स्टडआउट को बदलकर हल किया।

class FlushFile(object): 
    """Write-only flushing wrapper for file-type objects.""" 
    def __init__(self, f): 
     self.f = f 
    def write(self, x): 
     self.f.write(x) 
     self.f.flush() 

# Replace stdout with an automatically flushing version 
sys.stdout = FlushFile(sys.__stdout__) 
+0

मुझे नहीं लगता कि यह प्रत्येक sys.stdout.readline() के बाद sys.stdout.flush() को कॉल करने से अलग कैसे है, जो मैं करता हूं। मैंने subprocess के लिए bufsize = 0 सेट करने का भी प्रयास किया। – Paul

+9

उपप्रवाह में फ्लश की आवश्यकता है, न कि मूल प्रक्रिया। – bobince

+0

हां, उदाहरण में उपप्रोसेस एक पायथन लिपि भी है। तो subprocess में stdout को प्रतिस्थापित करें। अभिभावक प्रक्रिया में sys.stdout.flush() को कॉल करना कुछ भी नहीं करता है। –

7

प्रक्रिया आउटपुट buffered है। अधिक यूनिक्स ऑपरेटिंग सिस्टम (या सिगविन) पर, pexpect मॉड्यूल उपलब्ध है, जो बफरिंग से संबंधित मुद्दों से बचने के लिए सभी आवश्यक अवशोषणों को पढ़ता है। हालांकि, इन incantations के लिए एक काम pty module की आवश्यकता है, जो देशी (गैर-सिगविन) win32 पायथन बिल्ड पर उपलब्ध नहीं है।

उदाहरण के मामले में जहां आप उपप्रोसेस को नियंत्रित करते हैं, तो आप इसे केवल sys.stdout.flush() पर कॉल कर सकते हैं जहां आवश्यक हो - लेकिन मनमाने ढंग से उपप्रोसेसेस के लिए, वह विकल्प उपलब्ध नहीं है।

pexpect FAQ में भी the question "Why not just use a pipe (popen())?" देखें।

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