2009-10-31 4 views
6

में ओपूट फ़ाइल पुनर्निर्देशन मैं एक बैकअप स्क्रिप्ट लिख रहा हूं जिसे मैं हर रात एक cronjob में निष्पादित करना चाहता हूं।पायथन

स्क्रिप्ट sys.stdout और sys.stderr को आउटपुट फ़ाइल में सेट करता है ताकि यह पता चल सके कि क्या होता है।

बैकअप मैं निम्नलिखित कोड

cmd = 'rsync -av --del --stats --filter "- .thumbnails/" ' + \ 
    '--filter "- *~" --filter "- *.iso" --filter "- lost+found/" ' + \ 
    '--filter "- .cache/" --filter "- tmp/" --filter "- *.mp3" ' + \ 
    '--filter "- *.log" ' + srcDir + ' ' + dstDir 

print "Executing '"+cmd+"' ..." 
try: 
    sys.stdout.flush() 
    sys.stderr.flush() 
    retcode = subprocess.call(cmd, stdin = sys.stdin, stdout = sys.stdout, 
     stderr=sys.stderr, shell=False) 
    if retcode < 0: 
     print >>sys.stderr, "Command was terminated by signal", -retcode 
    elif retcode > 0: 
     print >>sys.stderr, "Command returned code ", retcode 
except OSError, e: 
    print >>sys.stderr, "Execution failed:", e 

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

यह क्यों हो रहा है और मैं इस व्यवहार को कैसे बदल सकता हूं?

+1

आप sys.stdout और sys.stderr कैसे सेट कर रहे हैं? – Ned

+1

यह सही लगता है और ऐसा व्यवहार नहीं करना चाहिए (और जब मैं कोशिश करता हूं), क्या आप अपने पर्यावरण का वर्णन कर सकते हैं (ओएस, खोल जिसमें से आप स्क्रिप्ट लॉन्च करते हैं)? – RedGlyph

+0

आप मौजूदा उपकरण जैसे 'rsnapshot' का उपयोग क्यों नहीं करते हैं (यह' rsync' का भी उपयोग करता है)। – jfs

उत्तर

3

मुझे स्टैक ओवरफ्लो उत्तर में समाधान here मिला।

sys.stderr = sys.stdout = logFile = open(tmpLogFileName, 'a', 0) 

यह अजगर बताता फाइल करने के लिए किसी भी उत्पादन बफर आवंटित नहीं करने के साथ

sys.stderr = sys.stdout = logFile = open(tmpLogFileName, 'a') 

बदलें।

+2

लेकिन यह बहुत जल्द छोड़ रहा है! :-) हम यह जानने में आपकी सहायता करना चाहते हैं कि क्यों फ्लश() काम नहीं कर रहा है; यदि आप केवल बफरिंग बंद कर देते हैं, असली समस्या - जो कुछ भी था - तय नहीं होगा। :-) –

+0

:] यह समाधान है। मैं हार नहीं मान रहा। मुझे लगता है कि वास्तविक समस्या फ्लश के अंदर है। इसकी जांच और हल करना मेरी क्षमता और मेरी जरूरतों से परे है। – chmike

+0

ठीक है, यह एक दिलचस्प गड़बड़ था, खुशी है कि आप इसे खत्म कर दिया :-) – RedGlyph

0

क्या आपने कोशिश ब्लॉक के बाहर फ्लश कॉल डालने का प्रयास किया है?

+2

नहीं क्योंकि इसका आउटपुट व्यवहार पर कोई प्रभाव नहीं होना चाहिए। ऐसा लगता है कि फ्लश वास्तव में फ्लश नहीं कर रहा है। प्रिंट "निष्पादन" निर्देश के लिए sys.stdout जोड़ना व्यवहार को बदलता नहीं है। – chmike

0

आप stderr क्यों प्रिंट कर रहे हैं? यदि उपद्रवी stderr पर लिखते समय stdout पर लिख रहा है, जो अजीब interleaving समझा सकता है।

+2

जब तक कॉल कमांड समाप्त नहीं होता तब तक मैं कॉल ब्लॉक मानता हूं। अन्यथा मैं रिटर्न कोड प्राप्त नहीं कर पाऊंगा। – chmike

+0

कॉल कहता है, जैसा कि आप कहते हैं, तो आप रिटर्न कोड पुनर्प्राप्त कर सकते हैं। लेकिन यह स्पष्ट नहीं करता है कि आप stderr के लिए क्यों प्रिंट कर रहे हैं। यदि आप उप फ़ाइल के समान फ़ाइल का उपयोग करते हैं, तो शायद आउटपुट ठीक से इंटरलीव किया जाएगा। –

+1

मैं एक ही फाइल का उपयोग कर रहा हूं क्योंकि मेरे पास प्रोग्राम की शुरुआत में निर्देश 'sys.stdout = sys.stderr = logFile = open ("/tmp/backup.log", "a") है। Stdout = sys.stdout आदि निर्दिष्ट करने के अलावा लॉग फ़ाइल को कॉल कमांड के लिए stdout फ़ाइल के रूप में सेट करता है। यह काम करता हैं।यह सिर्फ इतना है कि फ्लश() वास्तव में डिस्क पर buffered डेटा लिख ​​नहीं रहा है। – chmike