Home
img of docs

npm 安装过程中遇到权限错误(EACCES),不推荐直接使用 sudo。更好的做法是配置一个用户级的 npm 全局目录,避免动系统目录。

Adrian

/ Node

/ c:

/ u:

/ 7 min read


一学一个不吱声

遇到 EACCES 权限错误,说明 npm 试图向系统目录写入,但当前用户权限不足。配置一个用户级的全局目录是解决此问题的推荐方式。

🛠️ 配置用户级 npm 全局目录

请按以下步骤操作,全程无需使用 sudo

  1. 创建用户级全局目录 在终端中执行以下命令,在用户主目录下创建一个用于存放全局包的隐藏文件夹:

       mkdir ~/.npm-global

    你也可以使用 ~/.local~/.npm-packages 等其他路径,这里以 ~/.npm-global 为例。

  2. 配置 npm 使用新目录 告诉 npm 将全局包安装到刚刚创建的目录:

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

    此命令会修改 ~/.npmrc 文件,将 prefix 指向新目录。

  3. 将新目录添加到 PATH 环境变量 为了让系统能够找到通过 npm 全局安装的命令,需要将新目录下的 bin 文件夹添加到 PATH 中。

    由于 macOS Catalina 及之后版本默认使用 zsh,执行以下命令将配置追加到 ~/.zshrc 文件末尾:

       echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.zshrc

    如果你使用的是 bash,请将 ~/.zshrc 替换为 ~/.bash_profile

  4. 使配置立即生效 执行以下命令,让刚才的 PATH 修改在当前终端会话中生效:

       source ~/.zshrc

    如果你修改的是 ~/.bash_profile,则运行 source ~/.bash_profile

✅ 验证配置

配置完成后,可以通过以下方式验证是否成功:

  • 检查 npm 路径
       npm config get prefix
    应输出 /Users/你的用户名/.npm-global
  • 检查全局包安装位置
       npm root -g
    应输出 /Users/你的用户名/.npm-global/lib/node_modules
  • 测试安装: 现在可以尝试全局安装 Codex CLI,应该不会再出现权限错误:
       npm install -g @openai/codex
  • 验证命令: 安装完成后,检查 codex 命令的路径:
       which codex
    应输出 /Users/你的用户名/.npm-global/bin/codex,而不是 /opt/homebrew/bin/codex

🧹 可选:清理旧的 sudo 安装残留

如果你之前曾使用 sudo npm install -g 安装过包,建议清理旧文件,避免与新配置混淆。

1. 导出旧全局包清单

用旧 prefix 列出所有全局包:

   OLD_PREFIX=/usr/local
npm ls -g --depth=0 --prefix "$OLD_PREFIX"

如果只想拿到包名列表,可以用:

   OLD_PREFIX=/usr/local
npm ls -g --depth=0 --prefix "$OLD_PREFIX" --parseable | tail -n +2 | sed 's|.*/node_modules/||'

这会输出类似:

   typescript
eslint
@openai/codex

2. 批量重装到新的用户级目录

确保你已经配置好新 prefix:

   npm config get prefix
# 应该输出 /Users/你的用户名/.npm-global

然后批量重装:

   OLD_PREFIX=/usr/local
npm ls -g --depth=0 --prefix "$OLD_PREFIX" --parseable | tail -n +2 | sed 's|.*/node_modules/||' | while read -r pkg; do
  # 跳过 npm 自身和 corepack,避免破坏环境
  case "$pkg" in
    npm|corepack) continue ;;
  esac
  echo "正在安装: $pkg"
  npm install -g "$pkg"
done

这样所有旧包都会重新安装到 ~/.npm-global 下。

大概率会遇到的问题:EACCES: permission denied。 根本原因在于之前的 npm 缓存(~/.npm 目录)中,可能存有之前用 sudo 命令或系统级安装时留下的、属于 root 用户的文件。当你现在以普通用户身份运行时,npm 没有权限去修改或覆盖这些文件,因此触发了权限错误。

🛠️ 解决方案:修复缓存目录权限

要解决这个问题,需要把 ~/.npm 目录的所有权交还给你自己。请在终端中依次执行以下命令:

  1. ~/.npm 目录的所有权修改为当前用户: 这是最关键的一步,能从根本上解决权限问题。

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

    注意:执行此命令需要输入你的 Mac 开机密码。$(whoami) 会自动替换为你的用户名。

  2. 强制清理 npm 缓存: 修改权限后,清除可能已损坏的缓存记录,确保后续安装顺利。

       npm cache clean --force
  3. 验证缓存是否可用: 执行以下命令检查缓存目录状态,没有报错即代表修复成功。

       npm cache verify

完成上述修复后,就可以重新运行你之前的迁移脚本了。

3. 验证新目录

   npm list -g --depth=0
which -a node npm codex

确保 ~/.npm-global/binPATH 中排在系统目录前面。可以检查:

   echo $PATH

如果 /Users/你的用户名/.npm-global/bin 不在最前面,编辑 ~/.zshrc

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

然后:

   source ~/.zshrc

4. 清理旧系统包(可选,谨慎)

确认新装的包都能正常工作后,再考虑卸载旧包。卸载时要指定旧 prefix,避免误删新目录的包:

   OLD_PREFIX=/usr/local
npm ls -g --depth=0 --prefix "$OLD_PREFIX" --parseable | tail -n +2 | sed 's|.*/node_modules/||' | while read -r pkg; do
  case "$pkg" in
    npm|corepack) continue ;;
  esac
  echo "正在卸载旧包: $pkg"
  sudo npm uninstall -g --prefix "$OLD_PREFIX" "$pkg"
done

注意:

  • 不要卸载 npmcorepack,否则可能影响 Node 环境。
  • 如果某些包是通过 Homebrew 安装的,应该用 brew uninstall 卸载,而不是 npm uninstall
  • 如果不确定旧包是否重要,可以先保留,等新环境稳定后再清理。

完成以上步骤后,你的 npm 全局安装将完全在用户目录下进行,既解决了权限问题,也避免了污染系统目录。