我正在使用守护程序工具包启动侦听 Amazon SQS 消息的后台 ruby 进程。收到消息后,它将启动一个使用 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 并直接在 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 -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
......
这是不正确的,因为 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
感谢您的回答。最后,只需设置正确的 ENV 变量即可。
这是我必须更改的 ENV 变量。
- RBENV 使用RBENV_VERSION变量,RUBY_VERSION变量已弃用。
- 我启动进程的环境甚至没有 rbenv 填充程序目录的路径。
- 我尝试启动的过程依赖于将 gem 捆绑在 Gemfile 中,因此我还必须将 BUNDLE_GEMFILE env 变量设置为我的 Gemfile 的路径。