ruby - 使用不同版本的 Ruby 的 UNIX `system` 命令

标签 ruby shell unix heroku rake

我有一个包含以下内容的 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> - 直接从终端窗口中的命令行,它工作得很好。

因此看来 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

最佳答案

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

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

比较 ruby -e "puts ENV.inspect" 的输出与 bundle exec ruby -e "puts ENV.inspect"在使用 Bundler 的项目中。

这通常是您希望发生的情况,以便您始终使用 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 的干扰。 .

关于ruby - 使用不同版本的 Ruby 的 UNIX `system` 命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34515005/

相关文章:

python - Snakemake 在循环中使用规则

linux - 复制到unix中的目录时如何用空格替换文件名中的下划线

linux - nproc 和 ulimit 之间的区别?

ruby - 如何合并数组组?

mysql - 如何保证 Rails 中的 MySQL 锁获取顺序

ruby-on-rails - Rake Capistrano - 如何传递动态参数来执行 shell 命令

ruby-on-rails - 使用 ruby​​ 更改文件扩展名

Python sys.argv 从命令行自动转义我的参数?

C++ MFC 从 CLSID (GUID) 创建 IShellItem

go - 是否有查找完整文件权限的功能?