如何修复 npm 抛出无需 sudo 的错误

1498

我刚刚通过nodejs.org上的包安装了Node和NPM,但每当我尝试使用npm搜索或安装某些东西时,它都会抛出以下错误,除非我用sudo命令。我觉得这可能是一个权限问题?我已经是管理员了。

npm ERR! Error: EACCES, open '/Users/chietala/.npm/-/all/.cache.json'
npm ERR!  { [Error: EACCES, open '/Users/chietala/.npm/-/all/.cache.json']
npm ERR!   errno: 3,
npm ERR!   code: 'EACCES',
npm ERR!   path: '/Users/chietala/.npm/-/all/.cache.json' }
npm ERR! 
npm ERR! Please try running this command again as root/Administrator.

npm ERR! System Darwin 12.2.0
npm ERR! command "node" "/usr/local/bin/npm" "search" "bower"
npm ERR! cwd /Users/chietala
npm ERR! node -v v0.10.4
npm ERR! npm -v 1.2.18
npm ERR! path /Users/chietala/.npm/-/all/.cache.json
npm ERR! code EACCES
npm ERR! errno 3
npm ERR! stack Error: EACCES, open '/Users/chietala/.npm/-/all/.cache.json'
npm ERR! 
npm ERR! Additional logging details can be found in:
npm ERR!     /Users/chietala/npm-debug.log
npm ERR! not ok code 0

42
请考虑使用 NVM(而不是劫持权限)来解决问题,参见:https://dev59.com/rmQo5IYBdhLWcg3wUd-L#24404451 - Yves M.
2
@janaspage 你不能通过NPM(Node包管理器)安装node或NVM(Node版本管理器),这是不合理的。NPM与node一起提供(它们同时安装)。请查看维基百科页面:http://en.wikipedia.org/wiki/Npm_(software) - Yves M.
6
终于有比“sudo chown”更好的解决方案了:https://github.com/sindresorhus/guides/blob/master/npm-global-without-sudo.md - Dmitri Zaitsev
在OSX上,使用官方的pkg安装程序安装node时,这个解决方案不起作用。我使用了这个:https://dev59.com/rmQo5IYBdhLWcg3wUd-L#34968008 - fmquaglia
3
它解释了问题和解决方法:https://docs.npmjs.com/getting-started/fixing-npm-permissions - n00b
显示剩余4条评论
39个回答

2478

这看起来是您家目录权限的问题。要重新拥有.npm目录的所有权,请执行以下操作:

sudo chown -R $(whoami) ~/.npm

120
我以为 whoami 是一个占位符,但是按照原样输入它可以工作,所以它一定是一个我不理解的变量。 - SimplGy
144
whoami是一个实际的shell命令,http://en.wikipedia.org/wiki/Whoami。反引号符号(`)将`whoami`包围起来,确保它被正确执行并放置到chown命令中。 - Noah
这很好,但对于像我这样的npm新手来说,还有一个更完整的答案。可能需要创建一个新的/npm目录,并将npm指向使用它。请参见下面的suther的答案。 - logicOnAbstractions
使用下面的答案,npm config get prefix 显示我也必须对 ~/.nvm 进行此操作。 - Markus
谢谢!这个命令解决了许多Mac上的问题。 - sohammondal

740
安装Node时使用的权限将在进行诸如写入您的npm目录(npm link,npm install -g等)之类的操作时需要。您可能是以root权限运行了Node.js安装程序,这就是为什么全局包安装要求您成为root的原因。

解决方案 1:NVM

不要通过权限来安装 Node.js,选择正确的方式。

在开发机器上,不应该使用 root 权限来安装和运行 Node.js,否则像 npm linknpm install -g 这样的操作也需要相同的权限。

NVM(Node Version Manager)允许您无需 root 权限安装 Node.js,并且还允许您安装多个版本的 Node,便于进行开发。

  1. 卸载 Node(可能需要 root 权限)。这里 可能会有所帮助。
  2. 然后按照 此页面 的说明安装 NVM
  3. 通过 NVM 安装 Node:nvm install node

现在,npm linknpm install -g 将不再需要您以 root 身份运行。

编辑:另请参阅https://docs.npmjs.com/getting-started/fixing-npm-permissions


解决方案2:为特定用户全局安装包

不要通过修改权限来安装npm包,正确的方法是全局安装npm包。

如果您使用的是OSX或Linux系统,您可以创建一个专门用于全局包的用户目录,并设置npmnode以知道如何找到全局安装的包。

请参阅这篇优秀的文章,了解有关在不使用sudo的情况下全局安装npm模块的逐步说明。

另请参阅:npm的文档Fixing npm permissions


47
在所有发布的解决方案中,这里提供的NVM解决方案对我来说效果最好。强烈建议使用NVM而不是玩弄权限。 - wenincode
这些解决方案都对我没用。 - Mr. Panda
2
我从Snap Store安装了Node,但无法运行像npm install -g这样的命令。但是在尝试了NVM解决方案后,一切都顺利了。非常感谢您的答复。 - kevininhe
这篇文章也很有帮助:https://medium.com/devops-techable/how-to-install-nvm-node-version-manager-on-macos-with-homebrew-1bc10626181 - AndrewLeonardi
警告:仅使用 npm install node 将安装最新的(非LTS)版本!为了安装LTS(更安全)版本,请改用 npm install --lts - Borjovsky

401

同时,您需要在node_modules目录中具有写入权限:

sudo chown -R $USER /usr/local/lib/node_modules

147
我不知道为什么这个还在得到赞。将系统目录的所有权更改为特定用户是一种非常糟糕的做法!请参见下面的答案,了解其他解决方案(例如为节点用户创建单独的组)。 - Christopher Will
38
无论你做什么,绝对不要在 /usr/local/lib 或者 /usr/lib 上运行命令 'sudo chmod -R whoami',否则会损坏你的 sudoers 文件,让你自己后悔不已。 - qodeninja
我在更改节点专用内容的权限时四处探索,直到出现了一个关于无法安装“man页面”的错误...就像圣洁的^%$#一样,我不能在那里更改权限,因为那会影响到比节点更多的东西! - Michael

132

将“system-global”文件夹的所有者更改是一种破解方法。在新安装的情况下,我会配置NPM使用已经可写的位置来安装“user-global”程序:

npm config set prefix "${HOME}/npm"

然后确保将该文件夹添加到您的路径中:
export PATH="${PATH}:${HOME}/npm/bin"

为了避免未来出现问题,完全不要使用sudo npm ...
请参考@ErikAndreas的回答,了解NPM模块无法全局安装而不需要sudo,以及@sindresorhus提供的更长的逐步指南,其中还设置了$MANPATH

请注意,当前版本的Node的实际路径应为.npm.npm/bin - Chris Rutherford
@ChrisRutherford:正如您所看到的,路径是可配置的,因此它可以是您想要的任何可访问路径。在此答案/示例中选择 使用点名称,原因是 ~/.npm 会与原始问题中的“损坏”目录发生冲突,并且使用隐藏目录(至少在 *nix 系统上默认情况下)将更难以调试,当您“只想让事情正常工作”并继续您的一天。 - Joel Purra

98

注意!!!注意!!!注意!!!

使用chown或chmod不是解决方案,因为存在安全风险。

相反,请执行以下操作:

首先检查npm指向何处,如果您调用:

npm config get prefix

如果返回的是 /usr,则可以执行以下操作:
mkdir ~/.npm-global
export NPM_CONFIG_PREFIX=~/.npm-global
export PATH=$PATH:~/.npm-global/bin

这将在您的主目录中创建一个npm目录,并将npm指向它。
要使这些更改永久生效,您需要将导出命令添加到您的.bashrc文件中:
echo -e "export NPM_CONFIG_PREFIX=~/.npm-global\nexport PATH=\$PATH:~/.npm-global/bin" >> ~/.bashrc

1
这是我认为最好的解决方案 - 避免了与系统目录所有权混淆。使用sudo安装还可能导致后续权限问题(因为某些东西可能最终也被root拥有...) - logicOnAbstractions
1
那么对于已经全局安装的东西该怎么办呢?特别是如果其中一些是旧版本,而其他东西依赖于那个特定版本呢? - Michael
2
每当我获得一台新机器(无论是物理还是虚拟机),这就是我要安装的清单之一。最后一次看到它至少是在4年前,现在仍然非常相关。令人惊讶的是,它还没有被接受的答案。 - prateek_cs_2012

59

在安装 Recess (https://github.com/twitter/recess) 编译 Bootstrap 3 的 CSS 时,我遇到了这个问题。

安装 Recess 时:

-npm install recess -g
  1. 你需要像Noah所说的那样,在你的home目录中解锁权限:

sudo chown -R `whoami` ~/.npm
  • 你还需要对node_modules目录具有写入权限,就像Xilo所说的那样,如果还不起作用,请尝试以下方法:

  • sudo chown -R `whoami` /usr/local/lib/node_modules
    
  • 如果您仍然看到错误,可能还需要更正/usr/local权限

  • sudo chown -R `whoami` /usr/local
    
    请注意,如此帖子所示,在Mac上/usr/local/实际上不是一个系统目录,因此,这个答案对于Mac用户来说是完全“安全”的。但是,如果你使用的是Linux,请看下面Christopher Will的答案,那里提供了一个适用于多用户且系统目录安全(但更复杂)的解决方案。

    41
    这个想法很不好。你可能不希望系统目录被某个特定用户所拥有。除了严重的安全问题,这也不适用于多用户环境。 - Christopher Will
    1
    这让我感到非常害怕,因为它有如此多的赞。更改/usr/local的所有权在定义上是永久性的系统损坏,只能通过完整的操作系统安装来撤消。这是一个巨大的安全问题,并且有可能使一些系统无法启动。这个答案就像是一个病毒一样。很抱歉,但我必须标记它以便删除。 - aggregate1166877

    40

    其他答案建议更改系统目录的所有权或权限以指定用户。我强烈不建议这样做,这可能会变得非常尴尬,并可能搞乱整个系统!

    以下是一种更通用和更安全的方法,支持多用户。

    为node-users创建一个新组,并将所需用户添加到该组中。然后将node依赖文件/目录的所有权设置为该组。

    # Create new group
    sudo groupadd nodegrp 
    
    # Add user to group (logname is a variable and gets replaced by the currently logged in user)
    sudo usermod -a -G nodegrp `logname`
    
    # Instant access to group without re-login
    newgrp nodegrp
    
    # Check group - nodegrp should be listed as well now
    groups
    
    # Change group of node_modules, node, npm to new group 
    sudo chgrp -R nodegrp /usr/lib/node_modules/
    sudo chgrp nodegrp /usr/bin/node
    sudo chgrp nodegrp /usr/bin/npm
    
    # (You may want to change a couple of more files (like grunt etc) in your /usr/bin/ directory.)
    

    现在您可以轻松地作为用户安装您的模块

    npm install -g generator-angular
    

    一些模块(如grunt,bower,yo等)仍需要以root身份安装。这是因为它们在/user/bin/中创建符号链接。

    编辑

    三年后,我建议使用Node Version Manager。这能省去你很多时间和麻烦。


    3
    如果使用源代码安装了Node,虽然多用户可能会成为一个问题,但是所有模块都可以在不使用sudo的情况下完美运行。这也非常重要,因为在yeoman模块的情况下,人们无法通过sudo执行yeoman应用程序来更新生成器,因为它不允许sudo执行 :( - HeberLZ
    1
    在Linux上,我通常使用内置的“staff”组来为我的开发文件夹授予权限。此外,运行“chmod g+ws node_modules”是一个好主意,以确保您的组具有读/写权限。 - jackvsworld

    32

    如何解决npm install权限问题,错误提示为EACCES,请参考官方文档:https://docs.npmjs.com/getting-started/fixing-npm-permissions

    我在Mac OS X上使用.pkg安装程序安装node后遇到了这个问题。这里有一些很好的答案,但我还没有看到链接到npmjs.com的文档。

    选项1:更改npm默认目录的权限

    1. 找到npm目录的路径:

      npm config get prefix
      
      对于许多系统而言,这将是/usr/local

      警告:如果显示的路径只是/usr,请切换到选项2

    2. 更改npm目录的所有者为当前用户的名称(即您的用户名!):

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

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

    选项2:将npm的默认目录更改为另一个目录

    有时您不希望更改npm使用的默认目录(即/usr)的所有权,因为这可能会导致一些问题,例如如果您与其他用户共享系统。

    相反,您可以配置npm使用完全不同的目录。在我们的情况下,这将是我们主文件夹中的隐藏目录。

    1. 创建全局安装目录:

    mkdir ~/.npm-global
    
  • 配置npm以使用新的目录路径:

    npm config set prefix '~/.npm-global'
    
    打开或创建 ~/.profile 文件并添加此行:
    export PATH=~/.npm-global/bin:$PATH
    
  • 回到命令行,更新系统变量:

  • source ~/.profile
    

    2
    谢谢,这个方法对我有用,因为chown的解决方案没有用。你救了我。 - fmquaglia
    1
    我喜欢这个答案的第二个选项。(1)它没有使用sudo的安全漏洞,(2)它保留了其他用户的架构,(3)它引用了文档,并且(4)它包含了所需的命令行条目。感谢您的添加! - Tom Rose
    当您安装符号链接到 /usr/bin/ 的内容时会发生什么?现在只有您的用户可以访问它。如果您以其他用户身份登录,仍然无法访问,因为文件实际上位于另一个用户的主目录中! - Frans
    嗨@hoppykamper - 在第三步中,您如何“创建配置文件”?谢谢! - econobro
    @econobro 这取决于你的shell和操作系统。有时你应该使用.bashrc,其他时候是.bash_profile或者.profile。我无法回答你的具体情况。然而,要创建这个文件,只需输入touch ~/.profile。(~代表你的用户目录,位于/home下)。 - undefined

    20

    我遇到了这个问题,虽然确实需要让~/.npm的所有权归属于你的用户,但npm并没有在那里安装模块。

    真正解决我的问题的是以下命令:

    npm config set prefix ~/.npm
    export PATH="$PATH:$HOME/.npm/bin"
    

    这将确保您所有的全局安装都在此前缀下进行。而且,重要的是您的用户拥有此目录。


    4
    我必须在Ubuntu 20.04上做同样的事情。 - Stonecraft
    1
    这对于在WSL上使用Ubuntu 20.04非常有帮助。谢谢! - David
    这个帮了我很多,省了我很多痛苦。谢谢! - undefined

    12

    虽然我们这里需要更多的答案,但无论如何...

    Sindre Sorus撰写了一篇指南在OS X和Linux上安装npm软件包而不需要sudo权限,概述了如何在不影响权限的情况下进行干净的安装:

    以下是一种为给定用户全局安装软件包的方法。

    1. 创建用于全局软件包的目录

      mkdir "${HOME}/.npm-packages"
      
    2. 将此目录用于将来在您的.bashrc/.zshrc中使用:

    3. NPM_PACKAGES="${HOME}/.npm-packages"
      
    4. 指示npm在哪里存储全局安装的软件包。在您的$HOME/.npmrc文件中添加:

    5. prefix=${HOME}/.npm-packages
      
      确保节点可以找到它们。将以下内容添加到您的 .bashrc/.zshrc 文件中:
      NODE_PATH="$NPM_PACKAGES/lib/node_modules:$NODE_PATH"
      
      确保安装了二进制文件和手册页。将以下内容添加到您的.bashrc/.zshrc中:
      PATH="$NPM_PACKAGES/bin:$PATH"
      # Unset manpath so we can inherit from /etc/manpath via the `manpath`
      # command
      unset MANPATH # delete if you already modified MANPATH elsewhere in your config
      MANPATH="$NPM_PACKAGES/share/man:$(manpath)"
      

    如果你想要自动完成上述步骤,可以查看npm-g_nosudo

    查看本指南的源代码以获取最新更新。


    2
    感谢编辑 @AndyHayden :) 我建议使用上面评论中提到的方法:使用 NVM!https://dev59.com/rmQo5IYBdhLWcg3wUd-L#24404451 - ptim
    对我有效的唯一解决方案,不涉及权限混乱。我讨厌NPM及其愚蠢的权限问题。感谢您提供的解决方案! - RyanNerd

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