Запустите дочерний процесс в другой версии ruby

Я использую демон-комплект для запуска фонового процесса ruby, который прослушивает сообщения Amazon SQS. Как только сообщение получено, оно запускает дочерний процесс с Open3.popen3, который должен быть запущен в JRuby.

Фоновый процесс должен быть запущен в 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: команда не найдена"

Затем я отследил, как rbenv запускает свои исполняемые файлы, чтобы я мог обойти rbenv и запустить непосредственно исполняемый файл rp5 в JRuby.

Сначала я нашел исполняемый файл rp5 в папке: ~/.rbenv/ Version /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

Значит ли шебанг вверху означает, что этот исполняемый файл использует версию ruby ​​по умолчанию?

Можно ли даже запустить дочерний процесс в совершенно другой версии ruby?

Благодарю.

3 ответа

Это неверно из-за символа "~" для дома. Вам необходимо явно преобразовать ~ в абсолютный путь.

если ~ ~ /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

Вы пытались "заставить" его запустить в интерпретаторе, просто запустив 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 это должно просто сделать то, что вы ищете...

Спасибо за ваши ответы. В конце концов, это всего лишь вопрос настройки правильных переменных ENV.

Это были переменные ENV, которые мне пришлось изменить.

  1. rbenv использует переменную RBENV_VERSION, переменная RUBY_VERSION устарела.
  2. среда, в которой я запускал процесс, даже не имела PATH в каталоге rbenv shims.
  3. Процесс, который я пытался запустить, зависел от объединения драгоценных камней в Gemfile, поэтому мне также пришлось установить переменную BUNDLE_GEMFILE env в путь моего Gemfile.
Другие вопросы по тегам