我正在尝试通过运行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
答案 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的讨论。