Bundler无法在没有sudo权限的情况下安装任何gem

54
我尝试安装一个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 bundle,就可以更新而没有出现错误。但当前的情况是我需要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
8个回答

77

你可以在用户主目录下托管gems,这不需要root权限:

bundle install --path ~/.gem

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

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

或者在某些情况下:

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

参考: https://dev59.com/iW025IYBdhLWcg3wr4B6#5862327


更新:但请记住,如果您开始使用rbenv,并且此环境变量相同,则在使用两个不同版本的Ruby时可能会导致问题,因此您可能需要临时unset GEM_HOME或每次启动rbenv-ed Ruby时添加自定义变量。


这也适用于从Debian软件包安装的Ruby。 - amenthes
2
在这种情况下,您可能希望将~/.gem/ruby/<version>/bin添加到您的路径中。 - amenthes
谢谢,@amenthes。已添加到答案中。 - Nakilon
@akostadinov,尝试使用bundle exec gem install ...。您可以看到gem listbundle exec gem list显示不同的内容。而且,gem envbundle exec gem env也是如此。bundle exec使得以下命令在另一个环境中运行。一旦您开始使用bundle,您应该将其附加到在此目录中运行的其他命令中,以使它们在相同的环境中工作。有些人不喜欢在每个命令前面添加bundle exec,他们更喜欢在他们的Ruby代码中使用类似于require "bundler"等的东西,但我认为这很混乱。 - Nakilon
@Nakilon,我发现bundler不想与gem、标准的Linux发行版规范或任何其他工具合作。通常在命令前加上bundle exec是个好主意,但在我的情况下(并非理想的情况),最好以gem兼容的方式安装bundle。所以我最终找到了解决方法:https://dev59.com/kGQo5IYBdhLWcg3wBLny#64163511 - akostadinov
显示剩余2条评论

21

你的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)

谢谢!同时,您需要确保./rvm中的所有内容都属于“actual_user”(https://github.com/bundler/bundler/issues/6287#issuecomment-370886566) - Arek
有没有针对macOS的解决方案? - QuesterDesura

11

简述:

针对1.16.1版本

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

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

对于2.2.0 - 逻辑发生了变化,但在运行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停止以与gem install兼容的方式将gems安装为用户在用户本地gem目录中。

这意味着

  • gem install会安装到~/.gem/ruby/gems/gemname-gemversion
  • bundle install总是尝试安装到系统目录并需要sudo
  • bundle install --path ~/.gem会安装到~/.gem/ruby/2.5.0/gems/gemname-gemversion/顺便提一下,自bundler 2.x以来该标志似乎已过时/

没有文档说明如何请求安装gems的原始行为与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 && !@temporary.key?(key) && !@local_config.key?(key)。这意味着path必须设置,但不能在临时标志(我猜是--path)或项目本地配置中设置。这意味着它可以在用户全局配置文件或环境变量中设置。

这就是为什么我们需要退出项目目录,并将该设置设置为默认值的原因。但是,如果在用户全局配置文件中存在此键,则会更改bundler的行为,以便在不使用sudo的情况下将兼容于gem的依赖项安装到用户本地。

cd
bundle config path ~/.gem/ruby

感谢关注。


5
这是由于您安装Ruby的方式导致的。如果您不介意sudo,它仍然可以正常工作。归根结底,这只是您的笔记本电脑,而不是运行在银行中的服务器。如果您真的关心,按需要更改gem文件夹的所有者。

1
我以为我使用rvm安装了Ruby,但是我是个彻头彻尾的新手,所以可能有些困惑。你能稍微详细解释一下如何更改gem文件夹的所有者吗?它们在哪里? - emersonthis
4
进入路径 /path/to/gems,然后执行命令 sudo chown -R username:groupname *,其中的 username 和 groupname 需要替换成你自己的(在我的系统中是 denis:staff;如果你不知道你的是什么,请打开终端并输入 ls -l)。 - Denis de Bernardy
这可能是你后续问题的罪魁祸首。 - Denis de Bernardy
它们都应该归你所有。关于另一个问题,说实话我不知道。我从来没有使用过RVM(我很高兴使用sudo...),而Rails是我在研究RefineryCMS时放弃的东西——在我看来太混乱了。 - Denis de Bernardy
我很好奇想更多地了解你刚才说的话。你有时间聊一下吗? - emersonthis
显示剩余7条评论

2
今天我遇到了这个问题。这可能是一个独特的情况,但我从一个全局安装RVM(在/usr/local/rvm中)的系统中复制了一个Rails源代码树,然后将其复制到一个仅在每个用户中安装RVM(~/.rvm)的系统中。
我试图执行bundle install,但出现了“您的用户帐户不允许安装到系统Rubygems”的错误。经过大量搜索,我注意到在我的~/.rvm目录中有一个符号链接:
~/.rvm/gems/ruby-2.1.1/cache -> /usr/local/rvm/gems/cache

移除该符号链接后,bundle install 再次正常运行,无需使用 sudo

今天我在使用Vagrant和cachier插件时遇到了同样的问题,你的解决方案为我解决了难题,非常感谢! - Evgeny Chernyavskiy

1
我遇到了同样的问题,并发现Bundler在安装新的gems之前会检查是否对$GEM_HOME/build_info中找到的所有文件具有写权限。在我的情况下,它没有,因为虽然运行bundler的用户属于'rvm'用户组,而该组拥有所有这些文件,但是该组无法写入其中的某些文件。
这是因为我在root下安装了一些gems,而root具有umask 0022(由root创建的所有文件都不能被组写入),而不是其他人所具有的umask 0002,rvm也期望使用后者。

1
最好的解决方法似乎是使用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

0

如果你正在使用RVM,请执行以下两个步骤,你就可以了解一切

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

    sudo usermod -a -G rvm myUserName

  2. 确保所有RVM组中的用户都可以写入build_info文件夹

    sudo chmod 664 $GEM_HOME/build_info/*


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接