2009-09-07 11 views
34

से आउटपुट कैसे प्राप्त करें I निष्पादन Test_Pipe.py से आउटपुट चाहते हैं, मैंने लिनक्स पर कोड का पालन करने की कोशिश की लेकिन यह काम नहीं किया।subprocess.Popen()

Test_Pipe.py

import time 
while True : 
    print "Someting ..." 
    time.sleep(.1) 

Caller.py

import subprocess as subp 
import time 

proc = subp.Popen(["python", "Test_Pipe.py"], stdout=subp.PIPE, stdin=subp.PIPE) 

while True : 
    data = proc.stdout.readline() #block/wait 
    print data 
    time.sleep(.1) 

लाइन proc.stdout.readline() ब्लॉक किया गया था, इसलिए कोई डेटा प्रिंट बाहर।

+0

डुप्लिकेट: http://stackoverflow.com/search?q=%5Bpython%5D+subprocess+output, http://stackoverflow.com/questions/803265/getting-realtime-output-using-subprocess, http: //stackoverflow.com/questions/1277866/python-subprocess-module-looping-over-stdout-of-child-process –

उत्तर

39

आप स्पष्ट रूप से subprocess.communicate का उपयोग कर सकते हैं लेकिन मुझे लगता है कि आप वास्तविक समय इनपुट और आउटपुट की तलाश में हैं।

रीडलाइन अवरुद्ध कर दिया गया था क्योंकि प्रक्रिया शायद आपके इनपुट पर प्रतीक्षा कर रही है। आप निम्न की तरह इस पर काबू पाने के वर्ण दर वर्ण पढ़ सकते हैं:

import subprocess 
import sys 

process = subprocess.Popen(
    cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE 
) 

while True: 
    out = process.stdout.read(1) 
    if out == '' and process.poll() != None: 
     break 
    if out != '': 
     sys.stdout.write(out) 
     sys.stdout.flush() 
+2

[आपको इस मामले में 'process.poll() 'की आवश्यकता नहीं है] (http: // stackoverflow.com/a/17701672/4279)। – jfs

12

कई समस्याओं को हमेशा इस तरह के "वास्तविक समय में मुख्य प्रक्रिया को उपप्रक्रिया के उत्पादन हो रही है" के रूप में कार्य के लिए बफरिंग के साथ पैदा कर सकते से बचने के लिए, मैं सभी कार्यों को वांछित होने पर subprocess के बजाय, Windows पर सभी गैर-विंडोज प्लेटफॉर्म, wexpect के लिए pexpect का उपयोग करने की सलाह दें।

+0

pexpect के लिए अपडेट किया गया लिंक: https://github.com/pexpect/pexpect –

20

नाडिया का स्निपेट काम करता है लेकिन 1 बाइट बफर के साथ पढ़ने को कॉल करना बेहद अनुशंसित है। यह करने के लिए बेहतर तरीका fcntl

fcntl.fcntl(
    proc.stdout.fileno(), 
    fcntl.F_SETFL, 
    fcntl.fcntl(proc.stdout.fileno(), fcntl.F_GETFL) | os.O_NONBLOCK, 
) 

का उपयोग कर nonblocking और फिर अगर डेटा तैयार है परीक्षण करने के लिए चयन का उपयोग करने के लिए stdout फ़ाइल वर्णनकर्ता स्थापित करने के लिए किया जाएगा

while proc.poll() == None: 
    readx = select.select([proc.stdout.fileno()], [], [])[0] 
    if readx: 
     chunk = proc.stdout.read() 
     print chunk 

वह अपनी समस्या यह है कि सही था कॉलर.py और Test_Pipe.py के रूप में आपके द्वारा पोस्ट किए गए कार्यों से अलग होना चाहिए जैसा कि प्रदान किया गया है।

+0

यह ब्लॉक-बफरिंग समस्या के कारण प्रश्न में कोड के जितना जल्दी उत्पादन नहीं करेगा।मेरा जवाब देखें] (http://stackoverflow.com/a/17701672/4279)। – jfs

+0

कोड रीयलटाइम में उत्पादन का उत्पादन करता है। क्या आपको इसके साथ कोई समस्या है? –

+0

टिप्पणी में दिए गए लिंक का पालन करें। – jfs

7

Test_Pipe.py बफ़र्स अपने डिफ़ॉल्ट रूप से stdout तो Caller.py में proc किसी भी उत्पादन नहीं दिख रहा है जब तक बच्चे के बफर भरा हुआ है (यदि बफर आकार 8KB है तो यह एक मिनट के आसपास को भरने के लिए ले जाता है Test_Pipe.py का स्टडआउट बफर)।

उत्पादन unbuffered (लाइन बफ़र पाठ धाराओं के लिए) बनाने के लिए आप बच्चे को अजगर स्क्रिप्ट के -u flag दे सकते हैं। यह "वास्तविक समय" में लाइन द्वारा उपप्रक्रिया 'उत्पादन लाइन को पढ़ने के लिए अनुमति देता है: कैसे गैर अजगर बच्चे प्रक्रियाओं के लिए ब्लॉक बफरिंग समस्या को हल करने पर Python: read streaming input from subprocess.communicate() में

import sys 
from subprocess import Popen, PIPE 

proc = Popen([sys.executable, "-u", "Test_Pipe.py"], stdout=PIPE, bufsize=1) 
for line in iter(proc.stdout.readline, b''): 
    print line, 
proc.communicate() 

देखें लिंक।

+1

फिर आप 1 बाइट बफर का उपयोग कर रहे हैं जो अविश्वसनीय रूप से अक्षम है। –

+4

@ डेरिकपेटज़ोल्ड: गलत। 'bufsize = 1' का अर्थ है" लाइन-बफर "। यह वही बफर आकार का उपयोग 'bufsize = -1' के रूप में करता है। आप पाएंगे कि आपकी दोनों टिप्पणियां गलत हैं यदि आप वास्तव में कोड चलाने के लिए थे (समय प्रदर्शन की तुलना करें और पहले बाइट पढ़ने से पहले समय को मापें) – jfs

+1

मुझे ऐसा करने का तरीका पसंद है क्योंकि आप सीधे स्क्रीन पर प्रिंट कर सकते हैं और पॉपन के परिणामों को कुछ करने के लिए, और बाद में चेक त्रुटि कोड आदि पर संग्रहीत करें ... अंगूठे ऊपर =) मैं इसे bufsize के साथ चलाता हूं और मेरे कोड में मेरे लिए ठीक काम करता है। – pelos

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