NPM模块未使用sudo时无法全局安装

141

我刚刚重新安装了Ubuntu 12.04 LTS,在进行任何其他操作之前,我执行了以下步骤:

  1. 使用以下脚本通过包管理器安装了Node

    sudo apt-get update
    
    sudo apt-get install python-software-properties python g++ make
    
    sudo add-apt-repository ppa:chris-lea/node.js
    
    sudo apt-get update
    
    sudo apt-get install nodejs
    
    尝试全局安装yeoman、express、n,以及yeoman的生成器,但所有这些操作都返回相同的错误:

    npm ERR! Error: EACCES, symlink '../lib/node_modules/n/bin/n'

    npm ERR! { [Error: EACCES, symlink '../lib/node_modules/n/bin/n'] errno: 3, code: 'EACCES', path: '../lib/node_modules/n/bin/n' }

    npm ERR!

    npm ERR! 请尝试使用root/Administrator权限再次运行此命令。

    npm ERR! 系统 Linux 3.8.0-29-generic

    npm ERR! 命令 "/usr/bin/node" "/usr/bin/npm" "install" "-g" "-d" "n"

    npm ERR! 当前工作目录 /home/heberlz

    npm ERR! node -v v0.10.20

    npm ERR! npm -v 1.3.11

    npm ERR! 路径 ../lib/node_modules/n/bin/n

    npm ERR! code EACCES

    npm ERR! errno 3

    npm ERR! stack Error: EACCES, symlink '../lib/node_modules/n/bin/n'

    npm ERR!

    npm ERR! 更多日志详细信息请查看:

    npm ERR! /home/heberlz/npm-debug.log

    npm ERR! 不正确的代码 0

    我已经尝试了多次使用sudo恢复以下文件夹的所有权:~/.npm、/usr/lib/node、/usr/lib/node_modules,以及以下符号链接:/usr/bin/node、/usr/bin/nodejs,但均未成功。
    我需要在不使用sudo的情况下安装yeoman及其生成器,以免日后出现问题。

2
如果您想让npm在$HOME而不是/usr中安装全局软件包,请按照以下指南https://github.com/sindresorhus/guides/blob/master/npm-global-without-sudo.md。 - Colonel Panic
这是我用过的方法 https://github.com/nodejs/node-v0.x-archive/issues/3911#issuecomment-8956154 : ln -s /usr/bin/nodejs /usr/bin/node - Loïc MICHEL
可能是npm在没有sudo的情况下抛出错误的重复问题。 - Louis
17个回答

331

我在使用Ubuntu 12.04时,通过使用Chris Lea的PPA进行安装,以下步骤适用于我:

npm config set prefix '~/.npm-packages'

$HOME/.npm-packages/bin添加到$PATH

.bashrc中追加

export PATH="$PATH:$HOME/.npm-packages/bin"

更多信息请查看@passy的此答案


9
这个解决方案看起来更为简洁。如果你不喜欢在你的主目录中使用系统文件夹,你也可以选择一个位置,例如~/.local/share/npm。 - JeroenHoek
需要注意的是,在更改前缀后,您应该重新安装之前安装的所有全局模块,包括npm本身。 - Dziamid
这看起来不错,但我发现让用户有写入/usr/lib/node_modules/的权限要容易得多。或者甚至可以创建一个nodejs unix组,并给该组写入该目录的权限。 - mehulkar
需要补充的一个小细节是,你必须自己创建~/npm目录。否则,npm将会退出并显示ENOENT错误。 - Jason Farnsworth
适用于Ubuntu 14.04,使用DigitalOcean提供的Node.js安装教程https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-an-ubuntu-14-04-server。 - avenda
您也可以使用环境变量而不是npm配置(https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally),这样即使卸载或apt清除npm,它也会保留。例如,在`/etc/profile.d/npm.sh`中为所有用户全局设置:`export PATH="$PATH:/home/shared/npm/bin"; export NPM_CONFIG_PREFIX="/home/shared/npm";。在此示例中,我有一个具有写权限的npmjs组的/home/shared/npm`,其中包含可以安装npm软件包的用户。另外,您可能希望在更改路径后卸载所有软件包并重新安装。 - geekley

23
如果你的路径中已经包含$HOME/bin,那么一个更简单的解决方案就是...
npm config set prefix ~
  • 新的节点命令现在会安装到您的$HOME/bin目录中。
  • 无需更改路径!

由于这个讨论实际上是关于减少运行sudo的安全风险,您还应该知道,任何节点应用程序都有可能安装一个与您认为正在安装的已注册节点包名称不匹配的应用程序名称。因此,存在安全风险,即npm install将替换现有系统命令或您已经拥有的$HOME/bin中的命令。如果您担心,首先请检查您要安装的应用程序的package.json文件中的binscripts属性。

总的来说,最安全的做法是:

  • (a) 将 $HOME/bin 放在路径的最后,以避免系统命令被覆盖。
  • (b) 不要在 $PATH 中包含 "." 或任何相对路径,以避免意外运行当前目录中的命令。

参考:


1
npm 的另一个重要安全问题是,你在 github.com 上看到的节点包源代码可能与你从 npm.org 注册服务器安装的代码不同! - Tony O'Hagan
尽管理论上,一个精心制作的节点包可以愉快地安装在〜/bin中,但有些节点包(或其依赖包)仅经过了使用sudo进行安装的测试,因此请注意您可能会遇到未经测试的“安装环境”问题。与任何其他环境问题(如更改操作系统)一样,“编写一次,到处测试”的原则仍然适用。 - Tony O'Hagan
这种方法的缺点是npm会创建一个名为~/lib的额外目录。根据您的组织实践,这可能不是理想的选择。 - Mr. S

12

截至2014年10月:

Node.js可以从NodeSource Debian和Ubuntu二进制分发仓库中获取。

curl -sL https://deb.nodesource.com/setup | sudo bash -
sudo apt-get install -y nodejs

就这样。

过时的答案:

不使用sudo的最快方法如isaac在这里描述的

我强烈建议您不要使用sudo进行包管理! 包可以运行任意脚本,使得将sudo用于包管理器命令和剃头一样安全。当然,它很快, 肯定会穿过任何障碍,但你可能真的希望那个障碍留在那里。

我建议你做一次这个操作:

sudo chown -R $USER /usr/local

编辑:

有关将 /usr/local 的所有权更改为当前用户存在某些安全问题和功能限制:

话虽如此,如果您想在不使用sudo的情况下安装全局模块,我认为没有比提到的方法更好的解决方案(从实用的角度来看)。安全与易用性是一个非常广泛的话题,对于这个问题并没有简单的答案 - 它取决于您的需求。


23
这是一个不好的想法,因为它会使得所有 /usr/local 的文件都属于同一个用户。 - Reed G. Law
4
正如@ReedG.Law指出的那样,这真的是一个糟糕的想法。不要将/usr/local的所有权更改为任何特定的用户。 - Christopher Will
3
我必须同意Reed G Law的观点——更改/usr/local是一个非常非常糟糕的想法。在我的情况下,我正在查找指示并修改了该目录,但随后想起我必须与另一个开发人员共享这个环境。因此,我回退并(希望)将所有更改还原。这不仅涉及安全性,还涉及功能性。 - Lloyd Sargent
3
如果系统上__只有一个用户__,那么这种解决方案有什么不利之处吗? - connorbode
2
抱歉,我的意思是 /usr/local/lib/node_modulesnode - Creynders
显示剩余5条评论

11

问题是我使用sudo安装了node,为了避免在全局安装npm模块时出现错误,应该绝不使用sudo安装node

我的解决方案是这样的:重新安装node:

从nodejs.org下载最新的稳定版node源代码 #在我的情况下是node-v0.10.20.tar.gz

tar -zxf node-v0.10.20.tar.gz #解压源代码

cd node-v0.10.20 #进入解压缩文件夹

sudo chown -R $USER /usr/local

./configure --prefix=/usr/local && make && make install

需要注意的一点是,只占有/usr/local文件夹的所有权在我的情况下不起作用,因为node的安装本身是用sudo完成的

安装yeoman的最后一步:#虽然在yeoman.io上说做“npm install -g yo”已经安装了bower和grunt,但grunt的某些子模块会失败,所以我通过单独安装来修复这个问题

npm install -g bower

npm install -g grunt

npm install -g yo

npm install -g generator-angular


理论上很好,但有没有办法在不被迫构建Node并安装4个额外模块的情况下实现相同的效果,以便可以全局访问模块? - Dan Nissenbaum
所选答案正如您所需。这就是我两年前在没有其他公共解决方案的情况下所做的,但现在它已经无用了。 - HeberLZ

5
我使用环境变量和shell别名解决了这个问题:
export NPM_PREFIX=$HOME/node
alias npmg="npm -g --prefix $NPM_PREFIX"

我的经验是npm在.npmrc文件中没有遵守“prefix”配置设置。

3

找到npm目录的路径:

npm config get prefix

对于许多系统来说,这将是 /usr/local。
将npm目录的所有者更改为当前用户的名称(您的用户名!):
sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}

这将更改npm和其他一些工具使用的子文件夹(lib/node_modules、bin和share)的权限。

这是完整详情的链接。

https://docs.npmjs.com/getting-started/fixing-npm-permissions


重要提示。请尽量避免将“bin”和“share”添加到括号中。忽略此项可能会导致这些文件夹的所有权被更改为当前用户,并且在使用“sudo”安装新软件包时可能会出现问题,因为其所有权也会被更改。 - A.Ametov
这个命令会摧毁我的整个文件系统 :( - U.A

2
根据这个相似的SO帖子:npm throws error without sudo,看起来你可能在~/.npm目录上有一个所有权问题。
就像那个帖子中的答案一样,尝试:
sudo chown -R `whoami` ~/.npm

实际上,当我在第三步尝试解决问题时,这并没有像我所解释的那样起作用。问题是我使用sudo安装了node,这可能会在某些情况下造成麻烦。一旦我删除了node并从其源重新安装它,一切都开始按预期工作了! - HeberLZ
@HeberLZ 我认为你是对的,昨晚我在另一台机器上尝试了这个操作,但它并没有起作用。我还需要处理其他权限问题。仍然不确定从源代码安装npm时避免此类问题的最佳方法是什么。 - prasanthv
请在评论中提供问题链接或将当前问题标记为重复。复制其他问题的答案并不会有所帮助。 - givanse
@HeberLZ 这个回答的踩票是不恰当的,因为它涉及到你提出的问题标题。 - Sebastian Sastre
我不记得何时踩了这个回答的赞,但在我的情况下,你所写的并没有解决问题,所以我认为我可能是因为这个原因而踩了这个回答的赞。正如问题所述:“尝试递归地重新获取以下文件夹的所有权:~/.npm、/usr/lib/node、/usr/lib/node_modules,以及以下符号链接:/usr/bin/node、/usr/bin/nodejs,但完全没有成功。”我确实尝试过获取.npm和所有其他文件夹的所有权,但没有成功。 - HeberLZ
我不记得我何时对答案进行了负评,但正如问题所述,你写的是我尝试过但没有成功的步骤之一,这可能是我负评你的原因。更具体地说,在这段话中,我声明我已经尝试过并且没有成功:“递归地回收以下文件夹的所有权:~/.npm、/usr/lib/node、/usr/lib/node_modules,以及以下符号链接:/usr/bin/node、/usr/bin/nodejs,但完全没有成功。” 祝好 - HeberLZ

1

实际上,我只是更改了由root拥有的用户文件夹的权限:

sudo chown -R $USER ~/.config/configstore

然后我可以在不使用sudo的情况下进行“npm install”和“bower install”!运行良好!


1

该问题是由于npm文件夹的所有者不同所致。 解决此权限问题的最佳方法是执行以下命令 -

sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}

这将更改npm使用的子文件夹的权限


1

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