2010-02-25 7 views
34

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

मैं लगातार प्रत्येक लॉग फ़ाइल अवगत कराने के लिए एक पाश में प्रत्येक प्रक्रिया पर p.communicate() कॉल करने के लिए की जरूरत है, या वहाँ किसी तरह ताकि stdout और stderr स्वचालित रूप से फ़ाइल हैंडल को खोलने के लिए स्ट्रीम किए जाते हैं मूल Popen आदेश को लागू करने की है?

उत्तर

34

प्रति the docs के लिए पारित कर सकते हैं,

stdin, stdout और stderr निष्पादित कार्यक्रमों 'निर्दिष्ट मानक इनपुट, क्रमशः मानक आउटपुट और मानक त्रुटि फ़ाइल हैंडल। मान्य मान पीआईपीई हैं, एक मौजूदा फ़ाइल डिस्क्रिप्टर (एक सकारात्मक पूर्णांक), मौजूदा फ़ाइल ऑब्जेक्ट, और कोई नहीं।

तो बस गुजारें खुली के लिए लेखन नामित तर्क stdout= और stderr= के रूप में फ़ाइल की वस्तुओं और आप ठीक होना चाहिए!

+0

धन्यवाद। मैं कसम खा सकता था कि मैंने कोशिश की और एक त्रुटि मिली, लेकिन यह वही है जो मैं उम्मीद कर रहा था कि काम करेगा। –

+0

यह मेरे लिए काम नहीं करता है। मैं एक साथ दो प्रक्रियाओं को चला रहा हूं और stdout और stderr दोनों को एक लॉग फ़ाइल में सेव कर रहा हूं। अगर आउटपुट बहुत बड़ा हो जाता है, तो उपप्रोसेस में से एक लटकता है; कौन नहीं जानता मैं एक टिप्पणी में स्वरूपण का उपयोग नहीं कर सकता, इसलिए मैं नीचे "उत्तर" जोड़ूंगा। – jasper77

53

आप stdout और stderr पैरामीटर के रूप में Popen()

subprocess.Popen(self, args, bufsize=0, executable=None, stdin=None, stdout=None, 
       stderr=None, preexec_fn=None, close_fds=False, shell=False, 
       cwd=None, env=None, universal_newlines=False, startupinfo=None, 
       creationflags=0) 

को उदाहरण

>>> import subprocess 
>>> with open("stdout.txt","wb") as out, open("stderr.txt","wb") as err: 
... subprocess.Popen("ls",stdout=out,stderr=err) 
... 
<subprocess.Popen object at 0xa3519ec> 
>>> 
+3

वाह! मुझे नहीं पता था कि आप एक संदर्भ प्रबंधक में 'ओपन' की तरह चेन कर सकते हैं। #mindblown – hwjp

+0

मेरे लिए काम नहीं करता है! 'ओपन (" server.log "," wb ") के साथ बाहर: sp.call (server_cmd, stdout = out)' – Ayush

2

मैं साथ ही दो उपप्रोसेसेस चला रहा हूं, और आउटपुट को एक ही लॉग फ़ाइल में सहेज रहा हूं। मैंने लटका subprocesses को संभालने के लिए एक समय समाप्ति में भी बनाया है। जब आउटपुट बहुत बड़ा हो जाता है, तो टाइमआउट हमेशा ट्रिगर होता है, और किसी भी उपप्रजाति से stdout में से कोई भी लॉग फ़ाइल में सहेजा नहीं जाता है। उपरोक्त एलेक्स द्वारा उत्पन्न उत्तर इसे हल नहीं करता है।

# Currently open log file. 
log = None 

# If we send stdout to subprocess.PIPE, the tests with lots of output fill up the pipe and 
# make the script hang. So, write the subprocess's stdout directly to the log file. 
def run(cmd, logfile): 
    #print os.getcwd() 
    #print ("Running test: %s" % cmd) 
    global log 
    p = subprocess.Popen(cmd, shell=True, universal_newlines = True, stderr=subprocess.STDOUT, stdout=logfile) 
    log = logfile 
    return p 


# To make a subprocess capable of timing out 
class Alarm(Exception): 
    pass 

def alarm_handler(signum, frame): 
    log.flush() 
    raise Alarm 


#### 
## This function runs a given command with the given flags, and records the 
## results in a log file. 
#### 
def runTest(cmd_path, flags, name): 

    log = open(name, 'w') 

    print >> log, "header" 
    log.flush() 

    cmd1_ret = run(cmd_path + "command1 " + flags, log) 
    log.flush() 
    cmd2_ret = run(cmd_path + "command2", log) 
    #log.flush() 
    sys.stdout.flush() 

    start_timer = time.time() # time how long this took to finish 

    signal.signal(signal.SIGALRM, alarm_handler) 
    signal.alarm(5) #seconds 

    try: 
    cmd1_ret.communicate() 

    except Alarm: 
    print "myScript.py: Oops, taking too long!" 
    kill_string = ("kill -9 %d" % cmd1_ret.pid) 
    os.system(kill_string) 
    kill_string = ("kill -9 %d" % cmd2_ret.pid) 
    os.system(kill_string) 
    #sys.exit() 

    end_timer = time.time() 
    print >> log, "closing message" 

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