私はこの問題を解決するのに成功しました。類似の問題を抱えている人がこのページを見つけた場合には、いくつかの説明とともに、詳細を示します。しかし、あなたが詳細を気にしないなら、はここに短い答え:
を使用してください。(もちろん、独自のコマンドを使用して)次のように産卵は:
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
そしてここであまりにも多くの詳細と、長い答えです:
本当の問題は、もしプロセスのdoesnのようです明示的にそのstdoutをフラッシュすると、stdoutに書き込まれたものは、IOが最小限になるように、実際に送信されるのではなくバッファされます(これはであると思われます)。スループットが最大になるようにより少ないIOを介して)。あなたがstdoutを定期的にフラッシュするようにプロセスを簡単に変更できるなら、それがあなたの解決策になります。私の場合は、それはミキサーだったので、ソースを変更するために自分自身のような完全な騒ぎのために少し威圧していました。
しかし、これらのプロセスをシェルから実行すると、stdoutがシェルにリアルタイムで表示され、stdoutはバッファされていないようです。私が信じている別のプロセスから呼び出されたときだけバッファリングされますが、シェルが処理されている場合、stdoutはリアルタイムで見られ、バッファリングされません。
この動作は、出力をリアルタイムで収集する必要のある子プロセスとしてのルビプロセスでも発生する可能性があります。
そして、Rubyスクリプトはそれを呼び出すと、その出力を返す:
IO.popen("ruby random.rb") do |random|
random.each { |line| puts line }
end
あなたが取得しないことがわかりますただ、次の行で、スクリプト、random.rbを作成します結果はあなたが期待しているようにリアルタイムで、しかしその後はすべて一度に起こります。あなた自身がrandom.rbを実行しても、STDOUTはバッファされていますが、バッファされません。これは、random.rbのブロック内にSTDOUT.flush
ステートメントを追加することで解決できます。しかし、ソースを変更できない場合は、これを回避する必要があります。あなたはプロセスの外からそれを洗い流すことはできません。
サブプロセスがリアルタイムでシェルに印刷できるのであれば、これをリアルタイムでRubyで取り込む方法が必要です。そこには。あなたは、私は信じて(1.8.6とにかく)ルビーコアに含まれているPTYモジュールを使用する必要があります。悲しいことは、それが文書化されていないということです。しかし、私は幸いにも使用のいくつかの例を見つけました。
まず、PTYとは何かを説明するために、それはpseudo terminalの略です。基本的に、Rubyスクリプトは、コマンドをシェルに入力したばかりの実ユーザの場合と同じように、サブプロセスに自身を提示することができます。このため、ユーザーがシェルを介してプロセスを開始した場合(STDOUTがバッファされていないなど)に発生する変更された動作が発生します。別のプロセスがこのプロセスを開始したという事実を隠すことで、バッファされていないため、STDOUTをリアルタイムで収集することができます。次のコードを試してください、子として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 –