From: Tanaka Akira Date: 2010-05-08T20:33:54+09:00 Subject: [ruby-dev:41225] io/console IO#raw error when io is closed in the block io/console を使ってみたのですが、ちょっとうまく使えません。 IO#raw が tty の状態を必ず元にもどすんですが、それがちょっと困ります。 以下のように、pty を通して factor コマンドを使うことを考えます。 % ./ruby -rpty -e ' m, s = PTY.open r, w = IO.pipe pid = spawn("factor", :in=>r, :out=>s) r.close s.close w.puts "42"; p m.gets w.puts "133"; p m.gets ' "42: 2 3 7\r\n" "133: 7 19\r\n" 42 と 133 を factor コマンドで素因数分解できてだいたいうまくいっていますが、 改行が \r\n となってしまうのが気に入りません。 factor コマンド自体は \n を標準出力に出力しており、 それを \r\n にしているのは tty (pty) です。 ここで、pty じゃなくて pipe というわけにはいきません。 PTY.open を IO.pipe に変えて動かせば分かりますが、 factor コマンドが出力をバッファリングするため、ハングします。 (少なくとも Debian の factor コマンドでは) というわけで、やっぱり pty なので、それで改行の変換を抑制するには io/console の出番ということで、IO#raw を使うと、以下のように エラーになってしまいます。 % ./ruby -rpty -rio/console -e ' m, s = PTY.open r, w = IO.pipe s.raw { pid = spawn("factor", :in=>r, :out=>s) r.close s.close w.puts "42"; p m.gets w.puts "133"; p m.gets } ' "42: 2 3 7\n" "133: 7 19\n" -e:4:in `raw': closed stream (IOError) from -e:4:in `
' s は spawn 直後に close してあるので、tty の状態を元に戻そうとして すでに close されているというエラーになっています。 s を close することは、pipe から類推するといけなくはないように思います。 IO#raw で、ブロック内で close されたら、エラーにせずに単に抜ける、っていうのは どうでしょうか? -- [田中 哲][たなか あきら][Tanaka Akira]