[ruby-list:50778] 特定の状況下でIO#getsがストリームクローズされるまで読まない

From: haruka@...
Date: 2019-06-05 11:40:30 UTC
List: ruby-list #50778
正木です。

非常に限られた条件ではあるのですが、IO#gets、あるいはIO#eachを使用したときにストリームがクローズされるまでリードしてくれない状況が発生します。

概要としては次のようなものになります。

a.rbは

if msg = STDIN.gets(16, chomp: true)
   case msg
   ...
   when "command"
     exec("b.rb", ...)
   end
end

という感じでb.rbを呼び出します。
b.rbは

STDIN.each do |line|
   begin
     chat.force_encoding("UTF-8")
   rescue
     ...
   end
   if
     ...
   end
end

というような構成になっています。
このとき、「SSH経由でa.rbからb.rbを呼び出すと」 b.rbのSTDIN.eachが効きません。
これは、while line = STDIN.gets にした場合でも同じです。

SSH経由でない場合、あるいはb.rbを直接呼び出した場合は正しく動作します。

これを、例えばwhileを消して line = STDIN.gets と単独にするとちゃんと改行時点で読みます。
また、この直前に

while STDIN.gets
   p $_
end

のようなコードを入れると正しく動作するのですが、$_を外部ライブラリで定義されたメソッドの引数にすると動作しなくなります。
さらに、この単純な読み書きコードを書いたものを実行してから同箇所を削除すると、「その直後だけ正しく動作することがある」という不思議な状態になります。

execによる呼び出しをやめて、a.rbに直接b.rb相当のコードを書いた場合でもこの問題は発生します。


なにかわかる方いらっしゃいましたらご教示願えませんでしょうか

In This Thread

Prev Next