【问题标题】:UNIX `system` command using different version of Ruby使用不同版本 Ruby 的 UNIX `system` 命令
【发布时间】:2016-04-03 13:42:13
【问题描述】:

我有一个包含以下内容的 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 命令上崩溃并出现以下错误:

您的 Ruby 版本是 1.9.3,但您的 Gemfile 指定的是 2.2.2

但是,如果我直接从终端窗口中的命令行运行 Heroku 命令 - heroku pg:psql DATABASE -c 'DELETE FROM &lt;table name&gt;' -a &lt;heroku app name&gt;,它可以正常工作。

因此,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

【问题讨论】:

  • 我认为错误来自 Heroku,而不是您的本地计算机。尝试将系统命令替换为heroku run "ruby -v" 进行验证。有关更多故障排除,请参见此处:devcenter.heroku.com/articles/ruby-versions#troubleshooting。除此之外,我会尝试下面@nick-aschenbach 的建议。
  • 我认为这不是 Heroku 的问题。如果是这样,那么从命令行单独运行命令(不使用system)将产生相同的结果。但是从命令行运行它可以正常工作。 heroku run ruby -v -a &lt;app name&gt; 正确返回 ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]

标签: ruby shell unix heroku rake


【解决方案1】:

Ruby 在启动时会检查一些环境变量,您可以使用这些变量来控制加载路径和设置选项等内容。

Bundler 具有“传染性”,因为当您使用它时,它会添加一些环境变量,以便作为子进程执行的另一个 Ruby 进程将自动尝试使用具有相同 Gemfile 的 Bundler。

在使用 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(使用您正在使用的 Ruby 版本中的 Gem),然后尝试设置一切都根据您的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 干扰的情况下运行。

【讨论】:

  • 由于这是模糊地相关的,我认为您无法对我的other question 提供任何见解? :-)
【解决方案2】:

试试:

bundle exec rake <command>

这会在当前包的上下文中运行 rake 命令。

更多信息请点击此处:

What does bundle exec rake mean?

【讨论】:

  • 不幸的是,我在使用 bundle exec rake geo_data:heroku_import 时遇到了同样的错误。
  • 可能在路径中找不到 RVM 的 ruby​​,或者不是路径中的第一个 ruby​​。当您尝试时:which ruby 您是否看到类似 ~/.rvm/rubies/ruby-2.2.0/bin/ruby 的内容?
  • which ruby 正在输出/Users/jeffreydill/.rvm/rubies/ruby-2.2.2/bin/ruby
  • which rake 是否返回 /Users/jeffreydill/.rvm/rubies/ruby-2.2.2/bin/rake
  • 您是否为您的项目创建了 RVM ruby​​ gemset?我几乎总是用ruby-2.2.2 的文本创建.ruby-version.ruby-gemsetproject-name 的文本。 cd 退出目录并返回应该创建适当的 gemset:cd stack_model/ ruby-2.2.0 - #gemset created /Users/troy/.rvm/gems/ruby-2.2.0@stack-test ruby-2.2.0 - #generating stack-test wrappers..........
【解决方案3】:

看看这里How to fix "Your Ruby version is 1.9.3, but your Gemfile specified 2.0.0"

试试ruby -v

我已经通过运行rvm install 2.2.2 解决了这个问题。

【讨论】:

  • 谢谢,但我实际上已经安装了2.2.2。它也被设置为我的当前和默认值。 ruby -v 正确地给了我ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-darwin14]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-27
  • 1970-01-01
  • 2021-06-25
  • 2014-03-20
  • 1970-01-01
相关资源
最近更新 更多