14

ファイルを受け取り、そのファイルをいくつかのバイナリの 1 つに渡して処理し、変換プロセスのエラーを監視するコードを書いています。OSX で次のルーチンを作成してテストしましたが、Linux では不明な理由で失敗します。

#run the command, capture the output so it doesn't display
PTY.spawn(command) {|r,w,pid|
    until r.eof? do
      ##mark
      puts r.readline
    end
}

実行されるコマンドはさまざまで、## マークのコードは、問題をデバッグするためにローカル エコーに単純化されています。コマンドが実行され、スクリプトはターミナルに予期される出力を出力してから、例外をスローします。

Debian システムで生成されるエラーは次のとおりです。 Errno::EIO (Input/output error - /dev/pts/0):

私が思いついたすべてのコマンド文字列はそのエラーを生成し、ローカル エコー ブロックなしでコードを実行すると、問題なく実行されます。

PTY.spawn(command) {|r,w,pid|}

どちらの場合でも、コマンド自体は正常に実行されますが、debian linux が eof を pty に送信していないようです。PTY のドキュメント ページと ruby​​-doc の IO は、ここでは何の助けにもならないようです。

助言がありますか?ありがとう。

-vox-

4

3 に答える 3

19

そのため、ここで行われていることに本当に満足するには、PTY ライブラリの C ソースを読むところまで行かなければなりませんでした。

Ruby PTY のドキュメントには、ソース コード内のコメントが何を言っているのかが実際には書かれていません。

私の解決策は、ラッパー メソッドをまとめて、必要に応じてスクリプトから呼び出すことでした。また、プロセスが確実に終了するのを待っているメソッドと、からの終了ステータスへのアクセスをボックス化しました$?

# file: lib/safe_pty.rb

require 'pty'
module SafePty
  def self.spawn command, &block

    PTY.spawn(command) do |r,w,p|
      begin
        yield r,w,p
      rescue Errno::EIO
      ensure
        Process.wait p
      end
    end

    $?.exitstatus
  end
end

これは基本的に PTY.spawn と同じように使用されます。

require 'safe_pty'
exit_status = SafePty.spawn(command) do |r,w,pid|
  until r.eof? do
    logger.debug r.readline
  end
end

#test exit_status for zeroness

ruby-doc で完全に文書化されていなかったため、これが有効な応答であることがわかり、少しイライラしました。

于 2012-04-24T22:12:17.783 に答える
5

ここで Errno::EIO が発生するのは有効なようです (子プロセスが終了してストリームを閉じたことを意味するだけです)。

たとえば、Ruby の外部プロセスの STDOUT から継続的に読み取るで選択した回答を参照してください。

ところで、私はいくつかのテストを行いました。Ubuntu 10.04 上の Ruby 1.8.7 では、エラーは発生しません。Ruby 1.9.3 ではそうです。1.8 モードと 1.9 モードの両方の Ubuntu で JRuby 1.6.4 を使用すると、エラーは発生しません。OS X では、1.8.7、1.9.2、および 1.9.3 で、エラーは発生しません。動作は明らかに、Ruby のバージョンとプラットフォームに依存します。

于 2012-04-24T21:45:48.623 に答える