मुझे इस समस्या को हल करने में कुछ सफलता मिली है। यहां कुछ स्पष्टीकरण के साथ विवरण दिए गए हैं, यदि किसी को भी ऐसी ही समस्या हो रही है तो यह पृष्ठ पाता है। लेकिन अगर आपको विवरण की परवाह नहीं है, तो यहां संक्षिप्त उत्तर:
PTY का उपयोग करें।निम्नलिखित तरीके से अंडे (बेशक अपने स्वयं के आदेश के साथ):
require 'pty'
cmd = "blender -b mball.blend -o //renders/ -F JPEG -x 1 -f 1"
begin
PTY.spawn(cmd) do |stdout, stdin, pid|
begin
# Do stuff with the output here. Just printing to show it works
stdout.each { |line| print line }
rescue Errno::EIO
puts "Errno:EIO error, but this probably just means " +
"that the process has finished giving output"
end
end
rescue PTY::ChildExited
puts "The child process exited!"
end
और यहाँ, उत्तर है है जिस तरह से भी कई विवरण के साथ:
असली मुद्दा यह है कि अगर एक प्रक्रिया नहीं करता प्रतीत हो रहा है स्पष्ट रूप से अपने stdout flush नहीं है, तो प्रक्रिया को पूरा होने तक, वास्तव में भेजा जाने के बजाय stdout के लिए लिखा गया buffered है, ताकि आईओ को कम करने के लिए (यह स्पष्ट रूप से कई सी पुस्तकालयों के एक कार्यान्वयन विस्तार किया गया है, ताकि थ्रूपुट अधिकतम हो कम बार आईओ के माध्यम से)। यदि आप प्रक्रिया को आसानी से संशोधित कर सकते हैं ताकि यह नियमित रूप से stdout flushes, तो यह आपका समाधान होगा। मेरे मामले में, यह ब्लेंडर था, इसलिए स्रोत को संशोधित करने के लिए खुद को एक पूर्ण नोब के लिए थोड़ा डरा रहा था।
लेकिन जब आप इन प्रक्रियाओं को खोल से चलाते हैं, तो वे वास्तविक समय में खोल में स्टडआउट प्रदर्शित करते हैं, और stdout को buffered प्रतीत नहीं होता है। यह केवल एक ही प्रक्रिया से बुलाया जाता है जब मुझे विश्वास है, लेकिन यदि एक खोल का सामना किया जा रहा है, तो वास्तविक समय में stdout देखा जाता है, unbuffered।
यह व्यवहार एक रूबी प्रक्रिया के साथ भी देखा जा सकता है क्योंकि बच्चे की प्रक्रिया जिसका उत्पादन वास्तविक समय में एकत्र किया जाना चाहिए।
फिर एक गहरे लाल रंग का स्क्रिप्ट इसे कहते और इसके उत्पादन वापस जाने के लिए:
IO.popen("ruby random.rb") do |random|
random.each { |line| puts line }
end
आपको लगता है कि आप नहीं मिलता देखेंगे बस अनुसरण कर लाइन के साथ, एक स्क्रिप्ट, random.rb बनाने परिणामस्वरूप वास्तविक समय में आप उम्मीद कर सकते हैं, लेकिन सभी बाद में। STDOUT को buffered किया जा रहा है, भले ही आप random.rb चलाते हैं, यह buffered नहीं है। इसे random.rb में ब्लॉक के अंदर STDOUT.flush
कथन जोड़कर हल किया जा सकता है। लेकिन अगर आप स्रोत नहीं बदल सकते हैं, तो आपको इसके आसपास काम करना होगा। आप प्रक्रिया के बाहर से इसे फ्लश नहीं कर सकते हैं।
यदि उपप्रोसेस रीयल-टाइम में खोल के लिए प्रिंट कर सकता है, तो वास्तविक समय में रुबी के साथ इसे कैप्चर करने का एक तरीका होना चाहिए। और वहां है। आपको पीटीई मॉड्यूल का उपयोग करना है, रूबी कोर में शामिल है, मुझे विश्वास है (1.8.6 वैसे भी)। दुख की बात यह है कि यह दस्तावेज नहीं है। लेकिन मुझे सौभाग्य से उपयोग के कुछ उदाहरण मिले।
सबसे पहले, यह समझाने के लिए कि पीटीई क्या है, यह pseudo terminal है। असल में, यह रूबी स्क्रिप्ट को उपप्रोसेसर में पेश करने की अनुमति देता है जैसे कि यह एक वास्तविक उपयोगकर्ता है जिसने कमांड को शेल में टाइप किया है। तो कोई भी परिवर्तित व्यवहार जो तब होता है जब उपयोगकर्ता ने एक खोल के माध्यम से प्रक्रिया शुरू की है (जैसे कि STDOUT को इस मामले में buffered नहीं किया जा रहा है) होगा। इस तथ्य को समझते हुए कि एक और प्रक्रिया ने इस प्रक्रिया को शुरू किया है, आपको रीयल-टाइम में STDOUT एकत्र करने की अनुमति मिलती है, क्योंकि इसे buffered नहीं किया जा रहा है।
बच्चे के रूप में random.rb स्क्रिप्ट के साथ यह काम करने के लिए निम्नलिखित कोड का प्रयास करें,:,
require 'pty'
begin
PTY.spawn("ruby random.rb") do |stdout, stdin, pid|
begin
stdout.each { |line| print line }
rescue Errno::EIO
end
end
rescue PTY::ChildExited
puts "The child process exited!"
end
+1 - अच्छा और अच्छी तरह से किया गया! :) –
यह इतना अच्छा जवाब है। मेरा दिन बना दिया। –
यह बहुत अच्छा है, लेकिन मेरा मानना है कि stdin और stdout ब्लॉक पैरामीटर को स्वैप किया जाना चाहिए। देखें: http://www.ruby-doc.org/stdlib-1.9.3/libdoc/pty/rdoc/PTY.html#method-c-spawn –