

Ruby で PTY.getpty でコマンドを実行し、その出力 (標準出力・標準エラー出力) を取得したいと考えています。

ためしに下記のようなコードを書いたのですが、1つめの PTY.getpty 呼び出しでは期待通りコマンドの出力 `"1\r\n"` が得られる一方、2つめの
PTY.getpty 呼び出しでは r.eof? が最初から `true` になり、コマンドの出力が得られません (r.eof? の前に r.read
を呼んでも nil が返ってきます)。

[code]

    require "pty"
    
    puts "1. without sleep"
    PTY.getpty("echo 1") {|r, w, pid|
      # sleep 1
      until r.eof?
        p r.read(1000)
      end
      p PTY.check(pid)
    }
    
    puts "2. with sleep"
    PTY.getpty("echo 1") {|r, w, pid|
      sleep 1
      until r.eof?
        p r.read(1000)
      end
      p PTY.check(pid)
    }
    
[/code]

1つめと2つめの違いは `sleep 1` の有無だけですが、

  1. なぜ `sleep` の有無によって結果が変わるのか
  2. 安定してコマンドの出力を得る方法があるか

わかる方いらっしゃいましたらご教授いただけると幸いです。

(上記の例であれば Open3.capture3 などでも実装できると思いますが、実際には IO#expect を使ってパスワードの自動入力を行いたいため
PTY.getpty を使っています)

環境:  
macOS Monterey 12.2.1  
ruby 3.1.0p0 (2021-12-25 revision fb4df44d16) [x86_64-darwin21]


CC BY-SA 4.0
2022-03-14T05:19:11.707
86827
2022-03-15T01:38:56.890
2022-03-15T01:38:56.890
5789
5789
question
ruby
PTY.getpty で実行したコマンドの出力を IO#read で取得する際、処理時間 (sleep の有無) で結果が変わってしまう