【问题标题】:Start a child process in a different ruby version在不同的 ruby​​ 版本中启动子进程
【发布时间】:2014-01-17 16:49:20
【问题描述】:

我正在使用 daemon kit 启动一个后台 ruby​​ 进程来侦听 Amazon SQS 消息。一旦收到一条消息,它就会使用 Open3.popen3 启动一个需要在 JRuby 中运行的子进程。

后台进程需要在 MRI 中运行,因为 daemon kit 使用 Process.daemon 来守护进程。但到目前为止,我还不能强制子进程在 JRuby 中运行。

我正在使用 rbenv 来管理 ruby​​ 版本,所以起初我认为这会起作用:

Open3.popen3({"RUBY_VERSION" => "jruby-1.7.8"}, "rp5 run /path/to/sketch.rb") do |stdin, stdout, stderr, wait_thr|
  # read stderr and stdout for status and error information ....
end

但在子进程输出中我收到错误:“rbenv: jruby: command not found”

然后我跟踪了 rbenv 如何运行它的可执行文件,这样我就可以绕过 rbenv 并直接在 JRuby 中运行 rp5 可执行文件。

我首先在文件夹中找到了 rp5 可执行文件:~/.rbenv/versions/jruby-1.7.8/bin/rp5

#!/Users/fede/.rbenv/versions/jruby-1.7.8/bin/jruby
#
# This file was generated by RubyGems.
#
# The application 'ruby-processing' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = ">= 0"

if ARGV.first
  str = ARGV.first
  str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
  if str =~ /\A_(.*)_\z/
    version = $1
    ARGV.shift
  end
end

gem 'ruby-processing', version
load Gem.bin_path('ruby-processing', 'rp5', version)

然后我执行 Gem.bin_path 方法来查找它正在调用的 rp5 可执行文件。在 gem 里面: ~/.rbenv/versions/jruby-1.7.8/lib/ruby/gems/shared/gems/ruby-processing-2.3.1/bin/rp5 然后我尝试通过调用运行子进程此 rp5 可执行文件直接:

Open3.popen3("~/.rbenv/versions/jruby-1.7.8/lib/ruby/gems/shared/gems/ruby-processing-2.3.1/bin/rp5 run path/to/sketch.rb") do |stdin, stdout, stderr, wait_thr|
  # read stderr and stdout for status and error information ....
end

但我仍然收到相同的“未找到 jruby 命令”错误。

然后我检查了那个可执行文件:

#!/usr/bin/env ruby

file = __FILE__
if test(?l, file)
  require "pathname"
  file = Pathname.new(file).realpath
end

require File.expand_path(File.dirname(file) + "/../lib/ruby-processing")
Processing::Runner.execute

那么顶部的 shebang 是否意味着这个可执行文件正在使用默认的 ruby​​ 版本?

甚至可以在完全不同的 ruby​​ 版本中启动子进程吗?

谢谢。

【问题讨论】:

    标签: ruby jruby rbenv popen3


    【解决方案1】:

    您是否尝试通过简单地运行ruby -S 来“强制”它在解释器中运行,例如:

    Open3.popen3("/usr/bin/ruby ~/.rbenv/versions/jruby-1.7.8/lib/ruby/gems/shared/gems/ruby-processing-2.3.1/bin/rp5 run path/to/sketch.rb") do |stdin, stdout, stderr, wait_thr|
      # ...
    end
    

    所以首先找出 MRI ruby​​ 可执行文件的位置,然后使用它而不是 /usr/bin/ruby,它应该只是做你正在寻找的东西......

    【讨论】:

      【解决方案2】:

      这是不正确的,因为 '~' 字符代表 home。您需要将 ~ 显式转换为绝对路径。

      如果你的 ~ 是 /home/username/ 那么:

      Open3.popen3("/home/username/.rbenv/versions/jruby-1.7.8/lib/ruby/gems/shared/gems/ruby-processing-2.3.1/bin/rp5 run path/to/sketch.rb") do |stdin, stdout, stderr, wait_thr|
        # read stderr and stdout for status and error information ....
      end
      

      【讨论】:

        【解决方案3】:

        感谢您的回答。最后,只需设置正确的 ENV 变量即可。

        这是我必须更改的 ENV 变量。

        1. rbenv 使用 RBENV_VERSION 变量,不推荐使用 RUBY_VERSION 变量。
        2. 我启动进程的环境甚至没有指向 rbenv shims 目录的 PATH。
        3. 我尝试启动的进程依赖于将 gem 捆绑到 Gemfile 中,因此我还必须将 BUNDLE_GEMFILE 环境变量设置为我的 Gemfile 的路径。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-02-02
          • 2011-12-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-07-27
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多