【问题标题】:Bundler cannot install any gems without sudo没有 sudo,Bundler 无法安装任何 gem
【发布时间】:2013-04-28 22:11:22
【问题描述】:

我正在尝试安装一个 Rails 应用程序,但每次我使用 bundle 时,如果没有 sudo,它就会失败。我目前的情况是,只要将sudo 用于一切,一切正常,包括rails。我不认为这是正确的。

例如:

$ bundle update
Updating git://github.com/refinery/refinerycms.git
Fetching gem metadata from https://rubygems.org/.......
Fetching gem metadata from https://rubygems.org/..
Resolving dependencies...
Enter your password to install the bundled RubyGems to your system: 
Using rake (10.0.4) 
Using i18n (0.6.1) 
Using multi_json (1.7.2) 
Using rack-cache (1.2) 
Using rack-test (0.6.2) 
Installing hike (1.2.2) 
Errno::EACCES: Permission denied - /usr/local/rvm/gems/ruby-1.9.3-p194/build_info/hike-1.2.2.info
An error occurred while installing hike (1.2.2), and Bundler cannot continue.
Make sure that `gem install hike -v '1.2.2'` succeeds before bundling.

但是我按照它所说的去做并且它起作用了:

$ gem install hike -v '1.2.2' 
Successfully installed hike-1.2.2
Parsing documentation for hike-1.2.2
Installing ri documentation for hike-1.2.2
Done installing documentation for hike after 0 seconds
1 gem installed

对于不同的宝石,这种模式会一次又一次地重复。我不明白。为什么会这样?如果我使用 sudo 捆绑包将更新而不会出现此错误。但目前的情况是我需要sudo 来处理所有事情,包括rake...rails server 等。有些地方不对劲。

其他详细信息:我使用的是 OSX 10.8.3...

$ ruby -v
ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-darwin11.4.0]
$ gem -v
2.0.3
$ rvm -v
rvm 1.19.6 (stable) by Wayne E. Seguin <wayneeseguin@gmail.com>, Michal Papis <mpapis@gmail.com> [https://rvm.io/]

$ which ruby
/usr/local/rvm/rubies/ruby-1.9.3-p194/bin/ruby
$ which gem
/usr/local/rvm/rubies/ruby-1.9.3-p194/bin/gem
$ which rvm
/usr/local/rvm/bin/rvm

更新

我可以毫无错误地运行sudo bundle install 可能会提供信息。然后在bundle install 失败后立即出现如上所示的错误。这是为什么呢?

更新2

/usr/local/rvm[master]$ ls -l
total 56
-rw-rw-r--   1 root  rvm   566 May  4 12:59 LICENCE
-rw-rw-r--   1 root  rvm  8929 May  4 12:59 README
-rw-rw-r--   1 root  rvm     7 May  4 12:59 RELEASE
-rw-rw-r--   1 root  rvm     7 May  4 12:59 VERSION
drwxrwsr-x   3 root  rvm   102 May  4 01:34 archives
drwxrwsr-x  35 root  rvm  1190 May  4 12:59 bin
drwxrwsr-x  11 root  rvm   374 May  4 12:59 config
drwxrwsr-x   6 root  rvm   204 Jan 10 19:55 contrib
drwxrwsr-x   5 root  rvm   170 Jan 10 19:55 environments
drwxrwsr-x   3 root  rvm   102 Jan 10 19:55 examples
drwxrwsr-x   5 root  rvm   170 Jan 10 19:52 gems
drwxrwxr-x   6 ESL   rvm   204 May  4 12:59 gemsets
drwxrwsr-x  92 root  rvm  3128 May  4 01:34 help
drwxrwsr-x  11 root  rvm   374 May  4 01:34 hooks
-rw-rw-r--   1 root  rvm    11 May  4 12:59 installed.at
drwxrwsr-x   4 root  rvm   136 Jan 10 19:54 lib
drwxrwsr-x   5 root  rvm   170 May  4 12:55 log
drwxrwsr-x   2 root  rvm    68 Jan 10 19:52 man
drwxrwsr-x   9 root  rvm   306 Jan 10 19:52 patches
drwxrwxr-x   4 ESL   rvm   136 May  4 12:59 patchsets
drwxrwsr-x   4 root  rvm   136 Jan 10 19:55 rubies
drwxrwsr-x  64 root  rvm  2176 May  4 01:34 scripts
drwxrwsr-x   3 root  rvm   102 May  4 01:34 src
drwxrwsr-x   2 root  rvm    68 Jan 10 19:52 tmp
drwxrwsr-x   8 root  rvm   272 May  4 12:59 user
drwxrwsr-x   4 root  rvm   136 Jan 10 19:52 usr
drwxrwsr-x   5 root  rvm   170 Jan 10 19:55 wrappers

【问题讨论】:

    标签: ruby-on-rails ruby macos bundler osx-mountain-lion


    【解决方案1】:

    您可以在您的用户主文件夹中托管 gems,这不需要 root 权限:

    bundle install --path ~/.gem

    为避免手动传递此参数,请将 export GEM_HOME=$HOME/.gem 添加到您的 .bash_profile - 这解决了 Mac OS 和其他 *nix 系统上的 sudo 问题。然后,您可能还需要访问提供可执行文件的 gem(例如 bundler),所以也添加这个:

    PATH=$PATH:$HOME/.gem/bin
    

    或者在某些情况下:

    PATH=$PATH:$HOME/.gem/ruby/<version>/bin
    

    参考:https://stackoverflow.com/a/5862327/322020


    UPD:但请记住,如果您开始使用 rbenv,那么在使用太多不同版本的 Ruby 时,使用相同的环境变量可能会导致问题,因此您可能希望在每次启动时临时使用 unset GEM_HOME 或预先自定义一个rbenv-ed Ruby。

    【讨论】:

    • 这也适用于从 debian 包安装的 ruby​​。
    • 在这种情况下,您可能希望将~/.gem/ruby/&lt;version&gt;/bin 添加到您的路径中。
    • 谢谢,@amenthes。添加它来回答。
    • 使用这个,bundle install 安装在版本化目录下,但gem 安装在非版本化目录下。所以 gem 看不到 bundle 安装的 gems。如何确保gembundle 安装方式相同?
    • @akostadinov,试试bundle exec gem install ...。你可以看到gem listbundle exec gem list 显示不同的东西。 gem env 也与 bundle exec gem env 相比。 bundle exec 使以下命令在另一个环境中运行。一旦你开始使用bundle,你应该将它附加到你在这个目录中运行的其他命令中,以使它们在相同的环境中工作。一些不喜欢在所有内容前面加上bundle exec 的人更喜欢在他们的Ruby 代码中使用require "bundler" 之类的东西,但我认为这很混乱。
    【解决方案2】:

    您的 RVM gem 目录应该归 rvm 组所有。因此,与其更改所有权,不如简单地将用户添加到rvm 组:

    # $(whoami) evaluates to your username
    # You may want to change this to a different username depending on your config
    # but $(whoami) is a passable default
    usermod -a -G rvm $(whoami)
    

    【讨论】:

    【解决方案3】:

    这是由于您安装 ruby​​ 的方式造成的。

    坦率地说,如果您不介意 sudo,它*很好*。归根结底,它只是您的笔记本电脑……而不是银行中运行的服务器。

    如果您真的在乎,请根据需要 chown gem 文件夹。

    【讨论】:

    • 我以为我使用 rvm 安装了 Ruby,但我完全是 n00b,所以我可能会感到困惑。您能否稍微详细说明如何 chown gem 文件夹?他们在哪里?
    • cd /path/to/gems。然后sudo chown -R username:groupname *,其中用户名和组名是你自己的(在我的系统上,这将是denis:staff;如果你不知道你的,打开终端并输入ls -l)。
    • 根据您的问题,您的宝石在/usr/local/rvm/gems/
    • 我现在就这样做。我也刚刚注意到(在ls -l 之后) Gemfile.lock 归根用户所有。其他所有文件都归我所有。这很奇怪吗?
    • 这可能是你后续问题的罪魁祸首。
    【解决方案4】:

    tl;dr;

    对于 1.16.1

    cd $HOME
    bundle config path ~/.gem/ruby
    cd my_project
    bundle install
    

    对于 2.1.4 - 除了在运行 Bundler 后创建符号链接之外,我找不到其他方法。

    对于 2.2.0 - 逻辑 changed 但除了在运行 Bundler 后创建符号链接之外,我仍然找不到其他方法。

    cd myproject
    bundle install
    ln -s `ruby -rbundler -e "puts Bundler.bundle_path"` `ruby -e "puts Gem.path[0]"`
    

    替代方案 - 你可以试试gem install -g

    说明:

    事实证明,在某个时候(我猜 git blame 可以显示它,但我懒得检查),bundler 停止以与@987654326 兼容的方式在用户本地 gem 目录中以用户身份安装 gems @。

    意思是

    • gem install 安装在 ~/.gem/ruby/gems/gemname-gemversion
    • bundle install 尝试始终安装到系统目录并需要 sudo
    • bundle install --path ~/.gem 安装在 ~/.gem/ruby/2.5.0/gems/gemname-gemversion /btw 下,此标志似乎已被弃用,因为 bundler 2.x/

    没有文档说明如何请求将 gem 安装在 gem 所在位置的原始行为。甚至文件表明情况已经如此。

    所以查看 .../gems/bundler-2.1.4/lib/bundler/settings.rb.../gems/bundler-1.16.1/lib/bundler/settings.rb 的来源,我们可以观察到这个 gem(双关语):

        # for legacy reasons, the ruby scope isnt appended when the setting comes from ENV or the global config,
        # nor do we respect :disable_shared_gems
        def path
          key  = key_for(:path)
          path = ENV[key] || @global_config[key]
          if path && !@temporary.key?(key) && !@local_config.key?(key)
            return Path.new(path, false, false, false)
          end
    
          system_path = self["path.system"] || (self[:disable_shared_gems] == false)
          Path.new(self[:path], true, system_path, Bundler.feature_flag.default_install_uses_path?)
        end
    

    所以我们正在查看if path &amp;&amp; !@temporary.key?(key) &amp;&amp; !@local_config.key?(key) 行。这意味着必须设置path,但不能在临时标志中(我猜是--path),而不是在项目本地配置中。这意味着在用户全局配置或环境变量中。

    这就是为什么我们需要离开项目目录并将设置设置为默认值。但是在用户全局配置中看到此密钥会改变 bundler 行为,以便在没有 sudo 的用户本地安装与 gem 兼容的用户。

    cd
    bundle config path ~/.gem/ruby
    

    感谢关注。

    【讨论】:

      【解决方案5】:

      我今天发生了这种情况。这可能是一种特殊情况,但我已经将 Rails 源代码树从全局安装了 RVM 的系统(/usr/local/rvm 中的系统范围)复制到了每个用户仅安装了 RVM 的系统 (~/.rvm)。

      我试图做bundle install 并得到“你的用户帐户不允许安装到系统Rubygems。”错误。经过一番摸索,我注意到在我的~/.rvm 目录中有一个符号链接:

      ~/.rvm/gems/ruby-2.1.1/cache -> /usr/local/rvm/gems/cache
      

      删除该符号链接使 bundle install 在没有 sudo 的情况下再次工作。

      【讨论】:

      • 我今天在使用 Vagrant 和 cachier 插件时遇到了同样的问题,您的解决方案为我节省了时间,谢谢!
      【解决方案6】:

      我遇到了同样的问题,发现 Bundler 在安装新 gem 之前会检查它是否对找到的所有文件具有写入权限 $GEM_HOME/build_info。在我的情况下它没有,因为虽然运行 bundler 的用户在 'rvm' 用户组中并且该组拥有所有这些文件,但组不允许写入其中的一些。

      发生这种情况是因为我在 root 下安装了一些 gem,它具有 umask 0022(由 root 创建的所有文件,不能按组写入)而不是其他人拥有且 rvm 期望的 umask 0002。

      【讨论】:

        【解决方案7】:

        如果你使用的是 RVM,那么做这两个步骤,你会很成功

        1. 确保您的用户属于 RVM 组

          sudo usermod -a -G rvm myUserName

        2. 确保 build_info 对 RVM 组中的所有用户都是可写的

          sudo chmod 664 $GEM_HOME/build_info/*

        【讨论】:

          【解决方案8】:

          最好的解决方法似乎是使用 rbenv 来安装 ruby​​,如下所示 -

          rvm -v 
          rvm list
          rvm uninstall {version_to_uninstall}
          rvm use system - Switch to macOS default ruby version
          rvm implode - uninstall rvm 
          
          rbenv - Ruby Environment Manager - we will use this to install ruby
          brew install rbenv ruby-build
          rbenv install 2.6.0
          
          Add the following line to .bash_profile - 
          if which rbenv > /dev/null; then eval "$(rbenv init -)"; fi
          
          source ~/.bash_profile
          rbenv global 2.6.0
          ruby -v 
          

          运行 rbenv rehash

          rm -rf rbenv root /shims
          rbenv rehash
          

          终于运行了-

          bundle install
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-09-23
            • 1970-01-01
            • 2018-03-20
            • 2014-07-02
            • 2014-02-10
            • 2019-01-07
            • 2021-08-27
            相关资源
            最近更新 更多