2012-01-15 10 views
7

मैं वर्कफ़्लो प्रबंधक के साथ उपयोग के लिए एक रैपर वर्ग लिख रहा हूं। मैं (बच्चे प्रक्रिया subprocess.Popen के माध्यम से निष्पादित) एक आवेदन से उत्पादन लॉग इन करने की एक निश्चित तरीके से करना चाहते हैं:क्या मैं subprocess.Popen की आउटपुट स्ट्रीम को विभाजित/विलय कर सकता हूं?

  • बच्चे को एक लॉग फ़ाइल के लिए और माता पिता की stdout के पास जाना चाहिए की stdout,
  • की stderr बच्चे को एक अलग लॉगफाइल पर जाना चाहिए, लेकिन माता-पिता के stdout पर भी जाना चाहिए।

आईई। बच्चे से सभी उत्पादन पहुंचना चाहिए stdout (subprocess.Popen(..., stderr=subprocess.STDOUT) साथ की तरह पर विलय कर दिया, तो मैं आवरण से ही लॉग संदेशों के लिए stderr आरक्षित कर सकते हैं। दूसरी ओर, बच्चे की धाराओं अलग मान्यता अनुमति देने के लिए विभिन्न फाइलों के पास जाना चाहिए।

मैंने दो धाराओं (stdout और लॉग फ़ाइल) को एक साथ जोड़ने के लिए "टी" सहायक वर्ग का उपयोग करने का प्रयास किया है, ताकि Tee.write दोनों धाराओं को लिख सके। हालांकि, इसे Popen पर नहीं भेजा जा सकता क्योंकि "उपप्रोसेस" ओएस-स्तरीय फ़ंक्शंस का उपयोग करता है लिखने के लिए (यहां देखें: http://bugs.python.org/issue1631)

मेरे वर्तमान समाधान (नीचे कोड स्निपेट, here से अधिकतर अनुकूलित) की समस्या है stdout पर आउटपुट सही क्रम में प्रकट नहीं हो सकता है।

मैं इसे कैसे दूर कर सकता हूं? या क्या मुझे पूरी तरह से अलग दृष्टिकोण का उपयोग करना चाहिए? (अगर मैं नीचे दिए गए कोड के साथ चिपके रहते हैं, मैं os.read में बाइट की संख्या के लिए एक मूल्य चुनें कैसे करते हैं?)

import subprocess, select, sys, os 

call = ... # set this 
process = subprocess.Popen(call, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
logs = {process.stdout: open("out.log", "w"), process.stderr: open("err.log", "w")} 
done = {process.stdout: False, process.stderr: False} 
while (process.poll() is None) or (not all(done.values())): 
    ready = select.select([process.stdout, process.stderr], [], [])[0] 
    for stream in ready: 
     data = os.read(stream.fileno(), 1) 
     if data: 
      sys.stdout.write(data) 
      logs[stream].write(data) 
     else: 
      done[stream] = True 
logs[process.stdout].close() 
logs[process.stderr].close() 

वैसे, this solution "fcntl" का उपयोग मेरे लिए काम नहीं किया है। और मैं अभी तक अपने मामले में this solution को अनुकूलित करने का तरीका नहीं समझ पाया, इसलिए मैंने कोशिश नहीं की है।

उत्तर

1

आप shell=True सेट हैं, तो आप उपप्रक्रिया कि पाइप, पुनर्निर्देशन, और tee command शामिल करने के लिए एक कमांड स्ट्रिंग पारित कर सकते हैं।

+0

धन्यवाद। इसे देखने के बाद, ऐसा कुछ समाधान हो सकता है: http://unix.stackexchange.com/a/6431 हालांकि, मुझे अभी भी एक पायथन समाधान में दिलचस्पी होगी। – Hendrik

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