2011-03-02 17 views
8

द्वारा लाइन लाइन में फ़ाइल करने के लिए मेरी पायथन लिपि एक अन्य स्क्रिप्ट को कॉल करने के लिए उपप्रोसेसर का उपयोग करती है, जो उत्पादन को बहुत धीमी (लाइन-दर-रेखा आधार) उत्पन्न करती है। मैं फ़ाइल को लाइन से आउटपुट लाइन लिखना चाहता हूं, जब पूरी प्रक्रिया समाप्त न हो और पूरे आउटपुट को स्ट्रिंग के रूप में लिखें। निम्नलिखित कोड "स्क्रिप्ट" समाप्त होने पर आउटपुट को "फाइल" लिखता है।subprocess.Popen से stdout को सहेजना

args = ("script") 
file = open('output.txt', 'w') 
subprocess.Popen(args,stdout=file) 

यह भी संभव है? थेंक्स, क्रिस

उत्तर

1

हां, यह संभव है। यहां एक ऐसा फ़ंक्शन है जिसे मैंने पाइथन शेल स्क्रिप्ट के यूनिट परीक्षण करने के लिए टेस्ट हार्नेस उपयोग के लिए लिखा था।

def testrun(cmdline): 
    try: 
     cmdout, cmderr = "","" 
     cmdp = Popen(cmdline, shell=True,stdout=PIPE, stderr=PIPE) 
     cmdout,cmderr = cmdp.communicate() 
     retcode = cmdp.wait() 
     if retcode < 0: 
     print >>sys.stderr, "Child was terminated by signal", -retcode 
     else: 
     return (retcode,cmdout,cmderr) 
    except OSError, e: 
     return (e,cmdout,cmderr) 

समारोह एक टपल जो sys.exit() से खोल वापसी कोड मुद्दों में शामिल है, मानक आउटपुट पाठ, और मानक त्रुटि उत्पादन पाठ देता है। वे टेक्स्ट स्ट्रिंग दोनों हैं इसलिए प्रोसेसिंग से पहले उन्हें लाइनों में तोड़ने के लिए आपको splitlines का उपयोग करना होगा।

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

+0

आप pexpect का उपयोग कर एक उदाहरण दे सकते हैं? – perimosocordiae

+0

क्या आप pexpect वेबसाइट पर गए थे? धारा 8 में कई उदाहरण दिखाए जाते हैं कि इसका उपयोग कैसे किया जाता है। –

0

मैं एक प्रोग्रामिंग भाषा मैं पर काम कर रहा हूँ के लिए एक ही समस्या थी, और यह कर समाप्त हो गया: दुर्भाग्य से https://github.com/perimosocordiae/plumbum/blob/master/lib/stdlib.py#L21

, यह उत्पादन से पढ़ने शामिल है एक समय में एक चरित्र स्ट्रीम, एक जब तक लाइन जमा नई लाइन मिलती है। यह काम करता है, हालांकि, और मुझे वही व्यवहार प्राप्त करने के किसी अन्य तरीके से नहीं पता है।

+0

कृपया मेरे उत्तर में जोड़े गए pexpect लिंक को जांचें। –

+0

ऐसा प्रतीत होता है कि pexpect अभी तक py3k- संगत नहीं है। – perimosocordiae

2

आप सर्वेक्षण का उपयोग कर प्रक्रिया के साथ बातचीत कर सकते हैं, ताकि आप लाइन द्वारा लाइन इसके साथ सहभागिता करने का प्रयास कर सकते हैं:

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

process = subprocess.Popen(["ls", "-lart"], 
       bufsize=-1, # fully buffered (default) 
       stdin=subprocess.PIPE, 
       stdout=subprocess.PIPE, 
       stderr=subprocess.PIPE, 
       cwd=os.curdir, 
       env=os.environ) 
my_stdout_file = open("stdout.txt", "w") 
while True: 
    process.poll() 
    line = process.stdout.readline() 
    my_stdout_file.write(line) 
    eline = process.stderr.readline() 
    if line: 
     stdout_lines.append(line) 
    if eline: 
     stderr_lines.append(eline) 
    if (line == "" and eline == "" and 
     process.returncode != None): 
     break 
1

सोचा मैं एक समाधान है कि नहीं करता है साझा करते हैं .poll(), .wait() या .communicate() का उपयोग करें। अंक की एक जोड़ी:

  • मैं import codecs उपयोग करें, क्योंकि मेरी उत्पादन पूर्व एशियाई UTF-8 पाठ
  • मैं जाल को फ़िल्टर भ्रष्ट/अमान्य UTF-8 पाठ करने के लिए try: साथ प्रत्येक पंक्ति
  • मैं करने के लिए '\x0a' का उपयोग भी शामिल है मंच के बावजूद लिनक्स की नई लाइन को मजबूर करें।
  • उपयोग for line in iter(subproc.stderr.readline, ''): अगर आप stderr पर कब्जा करने के
  • यह दृष्टिकोण उत्पादन उत्पन्न करता है केवल जब बच्चे कार्यक्रम उत्पादन
  • बनाता का उपयोग kw शब्दकोश इस उदाहरण के लिए overkill है, लेकिन पता चलता है कि उपप्रक्रिया साथ ** kwargs उपयोग करने की आवश्यकता

कोड:

import subprocess 
import codecs 
import os 

kw = { 
    'bufsize': 0, 
    'executable': None, 
    'stdin': subprocess.PIPE, 
    'stdout': subprocess.PIPE, 
    'stderr': subprocess.PIPE, 
    'preexec_fn': None, 
    'close_fds': False, 
    'shell': False, 
    'cwd': None, 
    'env': None, 
    'universal_newlines': False, 
    'startupinfo': None, 
    'creationflags': 0, 
    } 

args = ['ls', '-lart'] 
kw['cwd'] = os.path.expanduser('~') 
logfile = os.path.expanduser('~/stdout.txt') 
stdlog = [] 

try: 
    subproc = subprocess.Popen(args,**kw) 
except: 
    print 'Error loading subprocess. Check arguments and kwargs' 
    exit() 

log = codecs.open(logfile,'w','utf-8') 
log.write(': Starting log for: \"%s\"\x0a'%(' '.join(args))) 
for line in iter(subproc.stdout.readline, ''): 
    try: 
     stdlog.append(line.rstrip().decode('utf-8')) 
     log.write(stdout[-1]+'\x0a') 
     print stdout[-1] 
    except: 
     pass 

log.flush() 
log.close() 
संबंधित मुद्दे