2012-03-21 5 views
4

私は、最終的にかなりの時間がかかるシステムプロセスを起動するルビースクリプトに取り組んでいます。私はこのプロセスの標準エラーから読んで、何が出力されているかによってそれに反応する必要があります。Rubyでカーネル#selectのポイントは何ですか?

私は現在、そのようにやっている:

Open3.popen3(cmd_to_run) do |stdin, stdout, stderr, waitthread| 
    stderr.each_line do |line| 
    # look out for specific lines and react to them accordingly 
    end 
end 

しかし、私はまた、実装が似たような達成するために見てきましたが、kernel#selectでそれをやって:

Open3.popen3(cmd_to_run) do |stdin, stdout, stderr, waitthread| 
    io = select([stderr], nil, nil, 30) 

    if io.nil? 
    log("Command timed out during Kernel#select") 
    return 
    end 

    io[0][0].each_line do |line| 
    # look out for specific lines and react to them accordingly 
    end 

end 

私はつるはしを読みましたなぜ私はそれを使うべきかについて私は混乱しているのですか?最初の方法はまったく同じです。

答えて

6

おそらく二つの理由:

  1. あなたはeach_line
  2. で複数のIOオブジェクト、電子を待つことができないことができ、タイムアウトを使用することができます。 g。 io = select([stdout, stderr])と複数のイベント(書き込みイベントや例外もあります)
+0

私はIOオブジェクトを「待機」する必要があると私は混乱していると思いますか?なぜ彼らはプロセスを開始した直後に利用できないのですか? – Brian

+1

IOオブジェクトはすぐに利用できますが、たとえば 'stdout'を読み込もうとすると(まだ)何もないと、監視プロセスがブロックされます。あなたのシステムプロセスが何らかの診断を 'stderr'に出力してあなたの返答を待っているとしたら、' stdout'ではなく 'stderr'だったので、' stdout'で何かを永遠に待っています。 'select'はリストから最初に利用可能なIOオブジェクトを返します。何かが起きたときにそれを処理し、何かがあるので' read'をブロックしません。 –

関連する問題