2010-07-26 11 views
20

मैं एक स्क्रिप्ट की तरह मिल गया है करने के लिए:बैश: बल exec'd प्रक्रिया unbuffered stdout

#!/bin/bash 
exec /usr/bin/some_binary > /tmp/my.log 2>&1 

समस्या some_binary stdout में अपने प्रवेश के सभी भेजता है है, और बफरिंग यह बनाता है, ताकि मैं केवल देखने कुछ लाइनों के टुकड़ों में उत्पादन। कुछ परेशान होने पर यह परेशान होता है और मुझे यह देखने की ज़रूरत है कि आखिरी पंक्ति क्या कहती है।

क्या ऐसा करने से पहले stdout unbuffered बनाने का कोई तरीका है जो कुछ_बिनरी को प्रभावित करेगा ताकि इसमें अधिक उपयोगी लॉगिंग हो?

(आवरण स्क्रिप्ट केवल कार्यकारी से पहले कुछ वातावरण चर सेट कर रहा है, इसलिए पर्ल या अजगर में एक समाधान भी संभव होगा।)

+5

डेनिस का जवाब * बिल्कुल * सही है। यहाँ पर क्यों। आउटिक्स के लिए सी स्टडीओ का उपयोग करने वाले यूनिक्स पर प्रोग्राम बफर करेंगे जब आउटपुट टर्मिनल पर नहीं जा रहा है (प्रदर्शन को बहुत बढ़ाता है) जब तक कि 'setvbuf' के साथ न कहें; शायद ही कोई उस से परेशान करता है। 'उम्मीद' प्रणाली (जिसमें से 'अनबफर' एक मामूली अनुप्रयोग है) यूनिक्स छद्म-टर्मिनल डिवाइस (ptys) के साथ काले जादू का उपयोग टर्मिनल के साथ प्रोग्राम चलाने के लिए करता है जो वास्तविक टर्मिनल नहीं है ताकि लपेटा गया प्रोग्राम बफर न हो इसका उत्पादन यह चालाक है, लेकिन चेतावनी दी जानी चाहिए: अधिकांश प्रणालियों में केवल सीमित संख्या में ptys हैं; एक स्वाभाविक रूप से unbuffered कार्यक्रम बेहतर है। –

+0

बीटीडब्ल्यू, यह विंडोज पर इतना अच्छा काम नहीं करता है। ऐसा इसलिए है क्योंकि उस प्लेटफ़ॉर्म पर अपेक्षा टर्मिनल जादू के बजाय डिबगिंग जादू का उपयोग करती है (क्योंकि यह वह क्षेत्र है जहां विंडोज * बहुत * अलग है)। –

+0

धन्यवाद। मैंने काले जादू पर भरोसा करने के बजाय सही चीज़ करने के लिए 'some_binary' को संशोधित करने का विकल्प चुनने का फैसला किया। 'उम्मीद' बहुत बढ़िया है, लेकिन मुझे यह नहीं चाहिए ... – bstpierre

उत्तर

13

आपको लगता है कि unbuffer स्क्रिप्ट expect के साथ आता है की मदद कर सकते हो सकता है।

+0

'echo -n।' या 'prinff "के साथ काम नहीं करता है।' 'मुझे अपने मामले में बैश – Davide

+0

में प्रगति पट्टी दिखाने के लिए चाहिए यह भी: http://stackoverflow.com/questions/1401002/trick-an-plication-into-thinking-its-stdin-is-interactive-not-a-pipe –

11

कुछ कमांड लाइन प्रोग्रामों में उनके स्टडआउट स्ट्रीम बफरिंग व्यवहार को संशोधित करने का विकल्प होता है। तो यह है कि अगर सी स्रोत उपलब्ध है जाने का रास्ता ...

# two command options ... 
man file | less -p '--no-buffer' 
man grep | less -p '--line-buffered' 

# ... and their respective source code 

# from: http://www.opensource.apple.com/source/file/file-6.2.1/file/src/file.c 
if(nobuffer) 
    (void) fflush(stdout); 

# from: http://www.opensource.apple.com/source/grep/grep-28/grep/src/grep.c 
if (line_buffered) 
    fflush (stdout); 

की उम्मीद unbuffer स्क्रिप्ट का उपयोग कर या कार्यक्रम के स्रोत कोड को संशोधित करने के लिए एक विकल्प के रूप में है, तो आप भी स्क्रिप्ट (1) का उपयोग करने के लिए stdout से बचने के लिए कोशिश कर सकते हैं एक पाइप की वजह से हिचकी:

देखें: Trick an application into thinking its stdin is interactive, not a pipe

# Linux 
script -c "[executable string]" /dev/null 

# FreeBSD, Mac OS X 
script -q /dev/null "[executable string]" 
+1

मैक ओएस एक्स पर, क्योंकि "स्क्रिप्ट" वापसी बदल सकती है "\ n" से "\ r \ n" से कोड, मुझे इस तरह चलाने की आवश्यकता है: 'script -q/dev/null कमांड ... | perl -pe '/ \ n/\ r \ n/g'' –

26

GNU coreutils-8.5 भी मैं संशोधित करने के लिए/ओ धारा बफरिंग stdbuf आदेश है।

http://www.pixelbeat.org/programming/stdio_buffering/

तो, अपने उदाहरण स्थिति में, केवल आह्वान:

exec stdbuf -oL /usr/bin/some_binary > /tmp/my.log 2>&1 

यह पाठ तुरंत पंक्ति-दर-पंक्ति (एक बार एक लाइन के साथ अंत के- पूरा हो गया है प्रकट करने के लिए अनुमति देगा सी "\n" सी में चरित्र)। यदि आप वास्तव में तत्काल आउटपुट चाहते हैं, तो इसके बजाय -o0 का उपयोग करें।

यदि आप पर unbuffer कमांड के माध्यम से निर्भरता पेश नहीं करना चाहते हैं तो यह तरीका अधिक वांछनीय हो सकता है। दूसरी तरफ, unbuffer रास्ता, यदि आपको some_binary को बेवकूफ बनाना है तो यह सोचने के लिए कि यह वास्तविक टीटी मानक आउटपुट का सामना कर रहा है।

2

जीएनयू कोरुटिल्स -8 में स्टडीबफ नामक एक प्रोग्राम शामिल है जो अनिवार्य रूप से एलडी_PRELOAD चाल करता है। यह लिनक्स पर काम करता है और बीएसडी सिस्टम पर काम करता है।

2

मैं एक जवाब के लिए इन्टरनेट में घूमते हैं, और इस में से कोई भी uniq के लिए काम किया जो stdbuf के अलावा सब कुछ बफ़र होना भी जिद्दी है:

{piped_command_here} | stdbuf -oL uniq | {more_piped_command_here}

1

एक वातावरण चर unbuffered करने के लिए टर्मिनल आईओ मोड सेट कर सकते हैं ।

निर्यात NSUnbufferedIO = हाँ

इस टर्मिनल unbuffered दोनों सी और Ojective-सी टर्मिनल उत्पादन आदेश के लिए सेट हो जाएगा।

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