2010-09-26 14 views
7

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

python MyLongRunngingScript.py | tee log.txt 

लेकिन यह किसी भी उत्पादन का उत्पादन नहीं करता है (बस चल अपेक्षा के अनुरूप स्क्रिप्ट उत्पादन का उत्पादन)। क्या कोई साधारण समाधान का प्रस्ताव दे सकता है? मैं मैक ओएस एक्स 10.6.4 का उपयोग कर रहा हूँ।

संपादित करें मैं अपनी स्क्रिप्ट में आउटपुट के लिए print का उपयोग कर रहा हूं।

उत्तर

16

आप सही रास्ते पर हैं लेकिन समस्या आउटपुट को बफरिंग पाइथन है।

सौभाग्य से वहाँ एक रास्ता यह उत्पादन बफ़र होना नहीं बताने के लिए है:

python -u MyLongRunngingScript.py | tee log.txt 
+3

'' को stdout'' '' stderr'' धारा रीडायरेक्ट करने के लिए मत भूलना यदि आपने उस पर कब्जा करना चाहते हैं: 'python -u MyLongRunngingScript.py 2> और 1 | tee log.txt'' – stephenfin

1

आप कभी-कभी अपनी स्क्रिप्ट में sys.stdout.flush() करने और tee के साथ चलने का प्रयास कर सकते हैं। जब stdout को tee पर रीडायरेक्ट किया गया है, तो यह सीधे टर्मिनल पर जा रहा है, उससे अधिक समय तक buffered हो सकता है।

2

तथ्य यह है कि आप कुछ भी नहीं देखते हैं, शायद इस तथ्य से संबंधित है कि बफरिंग हो रही है। तो आप पाठ के हर 4 को आउटपुट केवल आउटपुट प्राप्त करते हैं। प्लावित है

stdout_saved = sys.stdout 
logfile = open("log.txt","a") # check exception on that one. 
sys.stdout = OutputSplitter(stdout_saved, logfile) 

इस तरह, हर निर्गम (print शामिल है):

बजाय, कुछ इस तरह का प्रयास करें:

class OutputSplitter(object): 
    def __init__(self, real_output, *open_files): 
     self.__stdout = real_output 
     self.__fds = open_files 
     self.encoding = real_output.encoding 
    def write(self, string): 
     self.__stdout.write(string) # don't catch exception on that one. 
     self.__stdout.flush() 
     for fd in self.__fds: 
      try: 
       fd.write(string) 
       fd.flush() 
      except IOError: 
       pass # do what you want here. 
    def flush(self): 
     pass # already flushed 

तो ऐसे ही कुछ कोड के साथ उस वर्ग के साथ sys.stdout सजाने मानक आउटपुट और निर्दिष्ट फ़ाइल में। शायद tweaking की आवश्यकता हो सकती है क्योंकि मैंने उस कार्यान्वयन का परीक्षण नहीं किया है।

बेशक, संदेशों को प्रिंट करते समय एक (न्यूनतम समय) प्रदर्शन जुर्माना देखने की उम्मीद है।

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