【问题标题】:run a subprocess from ruby without waiting for it to return [duplicate]从ruby运行一个子进程而不等待它返回[重复]
【发布时间】:2012-11-24 00:42:12
【问题描述】:

可能重复:
Spawn a background process in 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 包装器。

#!/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 包装器太令人发指而无法获得任何批准,我可能会尝试一个工作线程池。好的。谢谢。

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

【问题讨论】:

标签: ruby subshell epipe


【解决方案1】:

嗯,你自己回答:Process.spawn:

Process.spawn("something");

【讨论】:

  • 这显然是最好的答案。它返回一个 pid,因此您仍然可以在需要时等待您的操作:pid = Process.spawn('action'); Process.wait pid;
【解决方案2】:

在 Ruby 1.9.3 中,你可以使用

 Process.fork do
   # do your long time job
 end

【讨论】:

  • 我使用了这个,然后使用了 Process.detach。谢谢。
【解决方案3】:

查看daemons gem。然后你可以这样做:

require 'daemons'
Daemons.run('some_script.rb')

【讨论】:

    猜你喜欢
    • 2012-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-22
    • 2011-02-05
    • 1970-01-01
    • 2021-03-29
    • 1970-01-01
    相关资源
    最近更新 更多