2013-05-15 7 views
5

पर एक प्रक्रिया का आउटपुट प्राप्त करना मैं subprocess.Popen का उपयोग कर प्रक्रिया चलाने के लिए एक पायथन स्क्रिप्ट का उपयोग कर रहा हूं और साथ ही आउटपुट को टेक्स्ट फ़ाइल में संग्रहीत करता हूं और साथ ही इसे कंसोल पर प्रिंट करता हूं।रनटाइम

result = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) 
for line in result.stdout.readlines(): #read and store result in log file 
    openfile.write("%s\n" %line) 
    print("%s" %line) 

कोड से ऊपर ठीक काम करता है, लेकिन उसके द्वारा यह पहली प्रक्रिया पूर्ण और परिणाम चर में उत्पादन संग्रहीत करता है: यह मेरा कोड है। उसके बाद लूप आउटपुट को स्टोर करता है और प्रिंट करता है।

लेकिन मैं रनटाइम पर आउटपुट चाहता हूं (क्योंकि मेरी प्रक्रिया को पूरा होने में घंटे लग सकते हैं, मुझे इन सभी घंटों के लिए कोई आउटपुट नहीं मिलता है)।

तो क्या कोई अन्य कार्य है जो मुझे गतिशील रूप से आउटपुट (रनटाइम पर) देता है, इसका मतलब है कि जैसे ही प्रक्रिया पहली पंक्ति देती है, इसे मुद्रित किया जाना चाहिए।

+1

मैं वास्तव में यह कभी नहीं की कोशिश की है, लेकिन मुझे लगता है कि आप अपने खुद के लिए भेजने के लिए अपेक्षा की जाती है पायथन 'फ़ाइल' ऑब्जेक्ट 'stdout' (या 'stdin', या' stderr') तर्क पर ऑब्जेक्ट। तब आपको उस फाइल को मतदान करना होगा। आपको उस दर्द को छोड़ने के लिए 'सबप्रोसेस' का आविष्कार किया गया था, लेकिन ऐसा लगता है कि आपके पास कोई विकल्प नहीं है। सौभाग्य। –

+1

_ "यह पहली बार प्रक्रिया को पूरा करता है और आउटपुट को परिणाम में स्टोर करता है" _ - यह सच नहीं है। – Eric

+0

"यह पहली बार प्रक्रिया को पूरा करता है और आउटपुट को परिणाम में संग्रहीत करता है" - यह सच नहीं है। खैर, जब मैं पॉपन कमांड चला रहा हूं, तब तक यह प्रक्रिया समाप्त होने तक चलती रहती है और फिर यह आगे कोडिंग निष्पादित करती है। अगर यह किसी अन्य तरीके से काम करता है, तो मैं उसे जानना चाहता हूं। – Niyojan

उत्तर

5

समस्या यह है कि .readlines() लौटने से पहले पूरे आउटपुट को प्राप्त करता है, क्योंकि यह एक पूर्ण सूची बनाता है। बस सीधे पुनरावृति:

for line in result.stdout: 
    print line 
+1

नोट: ['परिणामस्वरूप लाइन के लिए।stdout' पायथन 2 पर "वास्तविक समय" में रेखाएं नहीं लौटाता है, 'इसके अंदर लाइन के लिए' का उपयोग करें (result.stdout.readline, b '') 'इसके बजाय] (http://ideone.com/8KFawl) (आपका' प्रिंट लाइन' कथन से पता चलता है कि आप इसे पायथन 2 पर काम करने की उम्मीद करते हैं। [पायथन 3 पर यह ठीक काम करता है] (http://ideone.com/EUpeGV) – jfs

+0

हां, यह काम कर रहा है, मुझे वास्तविक समय पर आउटपुट मिल रहा है, धन्यवाद। – Niyojan

1

आप पाइप पर readline का उपयोग करके एक के बाद एक लाइन पर पुनरावृति कर सकते हैं:

while True: 
    line = result.stdout.readline() 
    print line.strip() 
    if not line: 
     break 

लाइनों एक अनुगामी \n जो मैं मुद्रण के लिए छीन होते हैं। जब प्रक्रिया समाप्त हो जाती है, तो रीडलाइन एक खाली स्ट्रिंग देता है, इसलिए आपको पता है कि कब रुकना है।

+1

मुझे खेद है, लेकिन आपको मेरा प्रश्न नहीं मिला। आपने जो सुझाव दिया है, मैं इसे लूप के लिए पहले से ही पूरा कर रहा हूं, जो मैं चाहता हूं वह लाइन आउटपुट द्वारा लाइन है जबकि प्रक्रिया अभी भी चल रही स्थिति में है। – Niyojan

+1

क्या आपने कोशिश की? आप 'रीडलाइन' का उपयोग कर रहे हैं, जो सभी लाइनों को लौटाता है। समाप्ति के बाद यह केवल संभव है। 'रीडलाइन' के साथ, आपको केवल अगले –

+0

परिणाम मिलते हैं .stdout मेरे लिए ठीक काम करता है, लेकिन आपकी line.strip() फ़ंक्शंस सहायक है क्योंकि मुझे इससे पहले" बी '\ r \ n' "बहुत धन्यवाद मिल रहा था, धन्यवाद – Niyojan

3

.readlines()की एक सूची सभी लाइनों जबकि खुले प्रक्रिया वापस आ जाएगी, जैसे कि, यह कुछ भी तक उपप्रक्रिया से सभी उत्पादन प्राप्त होता है वापस नहीं करता है देता है। "वास्तविक समय" में लाइन द्वारा लाइन पढ़ने के लिए:

import sys 
from subprocess import Popen, PIPE 

proc = Popen(cmd, shell=True, bufsize=1, stdout=PIPE) 
for line in proc.stdout: 
    openfile.write(line) 
    sys.stdout.buffer.write(line) 
    sys.stdout.buffer.flush() 
proc.stdout.close() 
proc.wait() 

नोट: उपप्रक्रिया का उपयोग करता है, तो ब्लॉक बफरिंग जब यह गैर-सहभागी मोड में चलाया जाता है; आपको pexpect, pty modules या stdbuf, unbuffer, script commands की आवश्यकता हो सकती है।

नोट: अजगर 2 पर, आप भी iter() उपयोग करने के लिए आवश्यकता हो सकती है, प्राप्त करने के लिए "वास्तविक समय" उत्पादन:

for line in iter(proc.stdout.readline, ""): 
    openfile.write(line) 
    print line,