2012-01-17 20 views
6

बैश में, इस उम्मीद के क्रम में उत्पादन देता है:रुबी से एसटीडीईआरआर आउटपुट रीडायरेक्ट करते समय पहले एसटीडीओयूटी आउटपुट से पहले क्यों आता है?

ruby -e "puts 'one'; raise 'two'" 
one 
-e:1:in `<main>': two (RuntimeError) 

लेकिन अगर मैं STDOUT करने के लिए STDERR अनुप्रेषित, मैं उत्पादन, है जो मैं नहीं करना चाहता से पहले त्रुटि मिलती है:

ruby -e "puts 'one'; raise 'two'" 2>&1 | cat 
-e:1:in `<main>': two (RuntimeError) 
one 

मैं आउटपुट को एक टेक्स्ट फ़ाइल में रीडायरेक्ट करना चाहता हूं (यह उपरोक्त cat जैसा व्यवहार करता है) और आउटपुट और अपवाद दोनों प्राप्त करता है, लेकिन उसी टर्मिनल में आउटपुट को देखते समय उसी क्रम में। क्या यह हासिल किया जा सकता है? हमेशा तुरंत आउटपुट

puts "one" 
$>.flush 

STDERR दूसरी ओर:

+1

STDEER हमेशा जबकि STDOUT आमतौर पर मुद्रित करने के लिए बफ़र है धारा में छपा है क्या करना चाहिए। –

उत्तर

2

यह क्योंकि STDOUT उत्पादन अभी नहीं है हमेशा की तरह, उत्पादन के लिए यह मजबूर करने के लिए है कि आप IO#flush का उपयोग करें।

+0

'आईओ # फ्लश 'एक बेहतर विकल्प है यदि बफर को एक से अधिक बार फ़्लश करने की आवश्यकता हो। 'फ्लश' एक एकल फ्लश है, 'सिंक' हैंडल-डाउन छोड़ देता है और इसे चलाने के लिए इसे प्राप्त करने के लिए आपको इसे घुमा देना होगा। :-) –

0

Maurício के और गिर Tacos के उत्तरों की पसंद के आधार पर, मैं इस के साथ आया था (How to turn on STDOUT.sync in ruby from the command line के माध्यम से):

ruby -r "/tmp/sync.rb" -e "puts 'one'; raise 'two'" 2>&1 | cat 
one 
-e:1:in `<main>': two (RuntimeError) 

जहां /tmp/sync.rb

STDOUT.sync=true 

शामिल या आप स्क्रिप्ट खुद को संशोधित कर सकते हैं, शुरुआत में उस पंक्ति को जोड़ें।

धन्यवाद!

+0

यही वह है जिसका मैंने इसका उपयोग किया: https://github.com/henrik/vim-ruby-runner/commit/d4b8cee927a265bbd016a42cf98f570eb33512ad –

9

यह लाइन-बफरिंग बनाम ब्लॉक-बफरिंग के कारण होता है। आप बफरिंग के प्रकार को नियंत्रित कर सकते हैं, आप उन्हें उस बिंदु पर फ्लश कर सकते हैं, जहां आप अपने आउटपुट को सिंक्रनाइज़ करना चाहते हैं, या आप बस बाहर निकलने तक प्रतीक्षा कर सकते हैं जिस बिंदु पर सबकुछ फिसल जाता है। जब तक आप इसे एक तरफ या दूसरे को मजबूर नहीं करते हैं, बफरिंग इस बात पर निर्भर करती है कि आउटपुट एक tty-type फ़ाइल डिस्क्रिप्टर है, इसलिए पाइप में पुनर्निर्देशन मोड को बदल देता है।

विशेष रूप

:

    true   false 
       ------------- -------------- 
$stdout.tty? line-buffered block-buffered 
$stderr.tty? line-buffered line-buffered 

आप उन्हें कॉन्फ़िगर कर सकते हैं दोनों एक ही तरह के साथ:

$stdout.sync = $stderr.sync = true # or false, of course 

मेरे परीक्षण का मामला:

$stdout.sync = $stderr.sync = true 
$stdout.puts 'stdout a' 
sleep 2 
$stdout.puts 'stdout b' 
sleep 2 
$stderr.puts 'stderr a' 
sleep 2 
$stderr.puts 'stderr b' 
sleep 2 


1. ttyname देखें (3)।

+1

अभी भी सहायक उत्तर। – sashaegorov

0

ruby -e STDOUT.sync=true -e "puts 'one'; raise 'two'" 2>&1 | cat

यह

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