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

时间:2022-03-02 00:07:48

I'm trying to run thin start 2>&1 in a subprocess by running fork/exec, and I'm reassigning STDOUT to a pipe so I can feed output through.

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

However, I don't get any output when Thin starts successfully. When it errors, I get the output in the wrong order—error text first, then the standard Thin startup messages.

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

I copied the code from Foreman, which handles this correctly. Any idea what's going on?

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

Code:

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 个解决方案

#1


3  

Data sent to $stdout isn't printed immediately -- it's buffered. On the other hand, $stderr isn't buffered and when you write to it you see results immediately. Let's see a minimal example.

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

STDOUT.puts :stdout
STDERR.puts :stderr

Save it as test.rb and replace thin start with ruby test.rb. Most probably stdout will be printed after stderr. In order to fix it we'll have to use the IO#sync= method

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

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

Now stdout will be printed synchronously, just as stderr is, and the resulting order of printed strings should be the intuitive one.

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

Initial lack of output from your child Thin process might be caused by the fact that the child isn't flushing data to STDOUT. First piece of data written to STDERR causes STDOUT to flush. Try adding STDOUT.sync = true somewhere in your application's or Thin's sources and see whether it helped.

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

See also a discussion on ruby-forum.com titled capture output in real time.

另请参阅ruby-forum.com上关于实时捕获输出的讨论。

#1


3  

Data sent to $stdout isn't printed immediately -- it's buffered. On the other hand, $stderr isn't buffered and when you write to it you see results immediately. Let's see a minimal example.

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

STDOUT.puts :stdout
STDERR.puts :stderr

Save it as test.rb and replace thin start with ruby test.rb. Most probably stdout will be printed after stderr. In order to fix it we'll have to use the IO#sync= method

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

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

Now stdout will be printed synchronously, just as stderr is, and the resulting order of printed strings should be the intuitive one.

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

Initial lack of output from your child Thin process might be caused by the fact that the child isn't flushing data to STDOUT. First piece of data written to STDERR causes STDOUT to flush. Try adding STDOUT.sync = true somewhere in your application's or Thin's sources and see whether it helped.

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

See also a discussion on ruby-forum.com titled capture output in real time.

另请参阅ruby-forum.com上关于实时捕获输出的讨论。