2

可能重复:
在 Ruby 中生成一个后台进程

花了几天时间戳这个。直到最近,我一直在使用操作系统中的 ruby​​ 1.8.7。我会用反引号调用一个子shell。subshel​​l 是一个 bash 包装器,它会在 stdout 和 stderr 都关闭的情况下调用在后台运行任何程序。然后它运行 disown 让 init 接管该过程,它会立即返回。这多年来一直很好,我会让这个循环过程在后台启动工作并立即报告“是的,它运行了,这就是我要告诉你的全部内容”。

我将所有东西都升级到 rvm 1.9.3 并且一切都很好,除了这个技巧。我开始怀疑这比我想承认的更像是一种黑客行为。在 1.9.3 中,当我生成该子 shell 时,我总是收到 EPIPE 错误。它说它的管道坏了。我可以接受它在 1.9.3 中不起作用,因为我在 1.8.7 中所做的似乎有点恶心。

我试过使用系统命令,也试过 open3:popen2。他们还和我一起抛出了一个 EPIPE,我称之为 disown wrapper。

#!/bin/bash

# this will crash ruby if you keep trying to read from it.
$* >&- &

disown %1

这是 disown 包装器。在红宝石中,我有类似的东西

    r=`/usr/local/bin/disown /usr/local/bin/job.sh`

当它运行时,它会抛出

/usr/local/bin/runner.rb:88:in ``': Broken pipe (Errno::EPIPE)

如果我不将(零)输出分配给 r 变量,则效果是相同的。并具有系统功能和Open3:popen2。

所以我的目标是简单地从 ruby​​ 运行命令,而不是等待它返回。这需要几个小时,我不需要跟踪它,只需生成它。如果它开始听起来像 ruby​​ 不能再这样做,或者如果我的 disown 包装器太令人发指而无法获得任何批准,我可能会尝试一个工作线程池。行。谢谢。

*编辑:感谢大家的精彩回答。我认为 Casper 向我展示了,如果我对红宝石术语有更好的处理,我可能会专注于此。对不起,如果这有点行人。我感谢大家的快速回答!

4

3 回答 3

3

好吧,你自己回答了Process.spawn::

Process.spawn("something");
于 2012-12-06T02:41:30.000 回答
2

查看守护进程 gem。然后你可以这样做:

require 'daemons'
Daemons.run('some_script.rb')
于 2012-12-06T02:29:10.330 回答
2

在 Ruby 1.9.3 中,你可以使用

 Process.fork do
   # do your long time job
 end
于 2012-12-06T02:31:02.263 回答