Ruby on Linux PTY在没有EOF的情况下消失,引发了Errno :: EIO

我正在编写一些带有文件的代码,将该文件传递给多个二进制文件之一进行处理,并监视转换过程中的错误。 我已经在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 } 

运行的命令变化很大,##标记处的代码已简化为本地回显以尝试调试问题。 该命令执行,脚本在终端中打印预期的输出,然后抛出exception。

它在Debian系统上产生的错误是: Errno::EIO (Input/output error - /dev/pts/0):

我可以提出的所有命令字符串都会产生错误,当我运行没有本地echo块的代码时,它运行得很好:

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

在任何一种情况下,命令本身执行正常,但似乎debian linux没有发送eof up the pty。 PTY文档页面和ruby-doc上的IO似乎没有任何帮助。

有什么建议? 谢谢。

-vox-

因此,我必须尽量读取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上完全没有记录。

在这里提出Errno :: EIO似乎是有效的(它只是意味着子进程已经完成并关闭了流),所以你应该期待并抓住它。

例如,请参阅Ruby中外部流程的STDOUT连续读取的选定答案和http://www.shanison.com/2010/09/11/ptychildexited-exception-and-ptys-exit-status/

顺便说一下,我做了一些测试。 在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版本和平台。