使用不同版本 Ruby 的 UNIX `system` 命令
UNIX `system` command using different version of Ruby
我有一个包含以下内容的 Rakefile:
namespace :geo_data do
desc 'Imports geo data to Heroku'
task :heroku_import => :environment do
system "heroku pg:psql DATABASE -c 'DELETE FROM <table name>' -a <heroku app name>"
# some more stuff...
end
end
每当我 运行 rake geo_data:heroku_import
时,它都会在我的 Heroku 命令上崩溃并出现以下错误:
Your Ruby version is 1.9.3, but your Gemfile specified 2.2.2
但是,如果我 运行 Heroku 命令 - heroku pg:psql DATABASE -c 'DELETE FROM <table name>' -a <heroku app name>
- 直接从终端的命令行 window,它工作正常。
因此 system
命令似乎使用了不同版本的 Ruby。
有趣的是,据我所知,我的机器上什至没有安装 1.9.3
。这是 rvm list
:
的输出
rvm rubies
ruby-2.0.0-p598 [ x86_64 ]
ruby-2.2.0 [ x86_64 ]
=* ruby-2.2.2 [ x86_64 ]
# => - current
# =* - current && default
# * - default
根据该输出,我没有安装 1.9.3
,2.2.2
被设置为我当前的 和 默认 Ruby 版本.
我确定 system
使用的是不同版本的 Ruby 是否正确,还是我遗漏了什么?如果它使用不同的版本,我怎样才能让它使用 2.2.2
(或者最好是 无论我的默认设置是什么 )?
更新
这是我的 Gemfile 的内容:
source 'https://rubygems.org'
ruby '2.2.2'
gem 'rails', '4.2.3'
gem 'rails-api'
gem 'spring', :group => :development
gem 'pg'
gem 'stripe'
gem 'jsonapi-resources', '0.7.0'
gem 'rails_api_auth'
gem 'rack-cors', require: 'rack/cors'
gem 'activerecord-postgis-adapter'
gem 'rgeo-geojson'
gem 'geocoder'
gem 'activerecord-import'
gem 'sidekiq'
gem 'unicorn'
group :development, :test do
gem 'rspec-rails'
gem 'forgery'
gem 'foreman'
end
group :development do
gem 'pry-rails'
end
尝试:
bundle exec rake <command>
这会在当前包的上下文中运行 rake 命令。
可在此处获取更多信息:
What does bundle exec rake mean?
看这里How to fix "Your Ruby version is 1.9.3, but your Gemfile specified 2.0.0"。
尝试ruby -v
我已经通过 运行 rvm install 2.2.2
.
解决了这个问题
启动时 Ruby 会检查一些环境变量,您可以使用它们来控制加载路径和设置选项等内容。
Bundler 具有“传染性”,因为当您使用它时,它会添加其中一些环境变量,以便作为子进程执行的另一个 Ruby 进程将自动尝试使用具有相同 Gemfile
.
在使用 Bundler 的项目中比较 ruby -e "puts ENV.inspect"
和 bundle exec ruby -e "puts ENV.inspect"
的输出。
这通常是您希望发生的情况,因此您始终使用 Gemfile
.
中定义的 Gems 和 Ruby 版本
heroku
命令包括它自己安装的 Ruby(它在我机器上的 /usr/local/heroku/ruby
中),它使用而不是你的普通版本。这是相当旧的 Ruby 版本,我的是 1.9.3p194。
因此,当您使用 system
到 运行 heroku
命令时,创建的 Ruby 进程会检查环境变量并加载 Bundler(使用 Gem 来自您正在使用的 Ruby 版本),然后尝试根据您的 Gemfile
设置所有内容。这是 Ruby 版本不匹配的地方。
要解决此问题,您需要告诉 Bundler 在启动子进程时不要包含各种环境变量。有几种方法可以解决这个问题,在你的情况下你想使用 Bundler.clean_system
而不是普通的 system
:
Bundler.clean_system "heroku pg:psql DATABASE -c 'DELETE FROM <table name>' -a <heroku app name>"
这将允许 Heroku 客户端 运行 不受 Bundler 和您的 Gemfile
的干扰。
我有一个包含以下内容的 Rakefile:
namespace :geo_data do
desc 'Imports geo data to Heroku'
task :heroku_import => :environment do
system "heroku pg:psql DATABASE -c 'DELETE FROM <table name>' -a <heroku app name>"
# some more stuff...
end
end
每当我 运行 rake geo_data:heroku_import
时,它都会在我的 Heroku 命令上崩溃并出现以下错误:
Your Ruby version is 1.9.3, but your Gemfile specified 2.2.2
但是,如果我 运行 Heroku 命令 - heroku pg:psql DATABASE -c 'DELETE FROM <table name>' -a <heroku app name>
- 直接从终端的命令行 window,它工作正常。
因此 system
命令似乎使用了不同版本的 Ruby。
有趣的是,据我所知,我的机器上什至没有安装 1.9.3
。这是 rvm list
:
rvm rubies
ruby-2.0.0-p598 [ x86_64 ]
ruby-2.2.0 [ x86_64 ]
=* ruby-2.2.2 [ x86_64 ]
# => - current
# =* - current && default
# * - default
根据该输出,我没有安装 1.9.3
,2.2.2
被设置为我当前的 和 默认 Ruby 版本.
我确定 system
使用的是不同版本的 Ruby 是否正确,还是我遗漏了什么?如果它使用不同的版本,我怎样才能让它使用 2.2.2
(或者最好是 无论我的默认设置是什么 )?
更新
这是我的 Gemfile 的内容:
source 'https://rubygems.org'
ruby '2.2.2'
gem 'rails', '4.2.3'
gem 'rails-api'
gem 'spring', :group => :development
gem 'pg'
gem 'stripe'
gem 'jsonapi-resources', '0.7.0'
gem 'rails_api_auth'
gem 'rack-cors', require: 'rack/cors'
gem 'activerecord-postgis-adapter'
gem 'rgeo-geojson'
gem 'geocoder'
gem 'activerecord-import'
gem 'sidekiq'
gem 'unicorn'
group :development, :test do
gem 'rspec-rails'
gem 'forgery'
gem 'foreman'
end
group :development do
gem 'pry-rails'
end
尝试:
bundle exec rake <command>
这会在当前包的上下文中运行 rake 命令。
可在此处获取更多信息:
What does bundle exec rake mean?
看这里How to fix "Your Ruby version is 1.9.3, but your Gemfile specified 2.0.0"。
尝试ruby -v
我已经通过 运行 rvm install 2.2.2
.
启动时 Ruby 会检查一些环境变量,您可以使用它们来控制加载路径和设置选项等内容。
Bundler 具有“传染性”,因为当您使用它时,它会添加其中一些环境变量,以便作为子进程执行的另一个 Ruby 进程将自动尝试使用具有相同 Gemfile
.
在使用 Bundler 的项目中比较 ruby -e "puts ENV.inspect"
和 bundle exec ruby -e "puts ENV.inspect"
的输出。
这通常是您希望发生的情况,因此您始终使用 Gemfile
.
heroku
命令包括它自己安装的 Ruby(它在我机器上的 /usr/local/heroku/ruby
中),它使用而不是你的普通版本。这是相当旧的 Ruby 版本,我的是 1.9.3p194。
因此,当您使用 system
到 运行 heroku
命令时,创建的 Ruby 进程会检查环境变量并加载 Bundler(使用 Gem 来自您正在使用的 Ruby 版本),然后尝试根据您的 Gemfile
设置所有内容。这是 Ruby 版本不匹配的地方。
要解决此问题,您需要告诉 Bundler 在启动子进程时不要包含各种环境变量。有几种方法可以解决这个问题,在你的情况下你想使用 Bundler.clean_system
而不是普通的 system
:
Bundler.clean_system "heroku pg:psql DATABASE -c 'DELETE FROM <table name>' -a <heroku app name>"
这将允许 Heroku 客户端 运行 不受 Bundler 和您的 Gemfile
的干扰。