以不同的ruby版本启动子进程

时间:2014-01-17 16:49:21

标签: ruby jruby rbenv popen3

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

后台进程需要在MRI中运行,因为守护进程套件使用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 command not found”错误。

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

#!/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版本中启动子进程吗?

感谢。

3 个答案:

答案 0 :(得分:0)

您是否曾尝试通过简单地运行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 ...

答案 1 :(得分:0)

这是不正确的,因为家庭的'〜'字符。您需要显式地将〜转换为绝对路径。

如果你的〜是/ 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

答案 2 :(得分:0)

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

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

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