从Ruby中执行fork / exec时,不会输出Thin

时间:2012-01-14 02:52:14

标签: ruby exec stdout pipe thin

我正在尝试通过运行thin start 2>&1 / fork在子流程中运行exec,并且我将STDOUT重新分配给管道,以便我可以通过输出。

然而,当Thin启动成功时,我没有得到任何输出。当它出错时,我首先输出错误的顺序错误文本,然后是标准的Thin启动消息。

我复制了Foreman的代码,它正确地处理了这个问题。知道发生了什么事吗?

代码:

reader, writer = IO.pipe
pid = fork do
  Process.setpgrp
  trap("INT", "IGNORE")
  $stdout.reopen writer
  reader.close
  exec("thin start 2>&1")
end
Process.detach pid
until reader.eof?
  puts reader.gets
end

1 个答案:

答案 0 :(得分:3)

发送到$stdout的数据不会立即打印 - 它已被缓冲。另一方面,$stderr没有缓冲,当你写它时,你会立即看到结果。让我们看一个最小的例子。

STDOUT.puts :stdout
STDERR.puts :stderr

将其另存为test.rb,并将thin start替换为ruby test.rb。最有可能stdout将在stderr之后打印。为了解决这个问题,我们必须使用IO#sync=方法

STDOUT.sync = true
STDOUT.puts :stdout
STDERR.puts :stderr

现在stdout将同步打印,就像stderr一样,打印字符串的结果顺序应该是直观的。

您孩子的输出初始缺乏精简过程可能是由于孩子没有将数据刷新到STDOUT。写入STDERR的第一个数据会导致STDOUT刷新。尝试在应用程序或Thin的源代码中添加STDOUT.sync = true,看看它是否有帮助。

另见ruby-forum.com上题为capture output in real time的讨论。