2013-02-26 86 views
6

जब एक पायथन स्क्रिप्ट से grep जैसे कमांड को मुद्रित आउटपुट पाइप करते हैं, तो स्क्रिप्ट से आउटपुट केवल संपूर्ण स्क्रिप्ट के पूरा होने के बाद फॉलो-अप कमांड पर पाइप किया जाता है।क्या वर्तमान में निष्पादित पायथन प्रोग्राम से आउटपुट पाइप लाइन-बाय-लाइन होने का कोई तरीका है?

उदाहरण के लिए

, एक स्क्रिप्ट test_grep.py निम्नलिखित की तरह में:

#!/usr/bin/env python 
from time import sleep 

print "message1" 
sleep(5) 
print "message2" 
sleep(5) 
print "message3" 

जब ./test_grep.py | grep message साथ कहा जाता है, कुछ भी नहीं 10 सेकंड है, जो समय में सभी तीन लाइनों दिखाई देगा के लिए दिखाई देगा।

एक स्क्रिप्ट test_grep.sh को यह तुलना करें:

#!/usr/bin/env bash 
echo "message1" 
sleep 5 
echo "message2" 
sleep 5 
echo "message3" 

./test_grep.sh | grep message तुरंत उत्पादन होगा message1, message2 और message3 से 5 सेकंड के अंतराल पर पीछा किया।

मुझे उम्मीद है कि ऐसा इसलिए है क्योंकि केवल एक बार पाइथन दुभाषिया निष्पादन समाप्त करने के बाद ही अगले आदेश के लिए उपलब्ध आउटपुट उपलब्ध होता है। क्या इस व्यवहार को बदलने का कोई तरीका है?

+0

दिलचस्प सवाल :) –

उत्तर

8

आप यह कर सकते हैं:

  • अजगर
  • में हर print निस्तब्धता द्वारा stdout की स्थापना unbuffered
  • होने के लिए तक stdout की स्थापना लाइन बफ़र होने के लिए तक

तुम भी कर सकते हैं बफरिंग अक्षम करने के लिए python -u पर कॉल करें।


मैं लाइन-बफरिंग विकल्प के लिए जाऊंगा क्योंकि यह सबसे प्राकृतिक लगता है।

open(file, mode='r', buffering=-1 ....) 

बफरिंग एक वैकल्पिक बफरिंग नीति सेट करने के लिए इस्तेमाल पूर्णांक है। बफरिंग बंद करने के लिए 0 पास करें (केवल बाइनरी मोड में अनुमति है), 1 से फिक्स्ड-साइज चंक बफर के आकार को इंगित करने के लिए लाइन बफरिंग (केवल टेक्स्ट मोड में उपयोग करने योग्य), और एक पूर्णांक> 1 का चयन करें।

आप बफरिंग निर्दिष्ट नहीं करते हैं जब (विशिष्ट "खुला") यह लाइन बफरिंग का उपयोग करेगा अगर यह पता लगाता है उत्पादन सीधे जा रहा है अपनी स्क्रीन कंसोल के साथ TTY है, यानी है। यदि आप पाइप आउटपुट या इसे फ़ाइल में रीडायरेक्ट करते हैं तो यह वापस एक बड़े (4 के/8 के) बफर पर स्विच हो जाएगा।


कैसे आप "stdout सेट लाइन बफ़र किया जाना है" करते हैं?

आप sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 1) के माध्यम से फिर से खोल सकते हैं।

+0

'sys.stdout.flush()' नौकरी करता है। – Fabian

+0

आप कैसे "लाइन-बफर होने के लिए stdout सेट करें"? मुझे फ़ाइल ऑब्जेक्ट्स ('sys.stdout') में कुछ भी नहीं मिला है जो इसकी अनुमति देता है। शायद stdout की फ़ाइल डिस्क्रिप्टर ('sys.stdout.fileno') के माध्यम से? – EOL

+0

@EOL मैंने जवाब संपादित किया। टीएल; डीआर: 'एफडीओपेन '। – cnicutar