用 npx 跑 CLI 工具,我遇到权限报错
项目里要批量改几十个 JSON 文件的字段,写脚本太啰嗦,我直接用了 npx json -I -f a.json -e 'this.x=1'。本机 Node 18.17,macOS 13,npm 9.6,第一次跑就报 EACCES: permission denied, open '/Users/xxx/.npm/_npx/.../node_modules/.bin/json'。文件数量不多,但权限问题卡了半小时,记一下。
我的做法是先把 npx 缓存目录的权限修回来:
sudo chown -R $(id -u):$(id -g) ~/.npm/_npx
然后确认 npm 的全局前缀没有混用:
npm config get prefix
# 输出 /Users/xxx/.nvm/versions/node/v18.17.0
如果之前用 sudo 装过全局包,~/.npm 下会有 root 拥有的文件,npx 解包时就会撞上。我接着跑了:
npm cache verify
npx --yes json -I -f a.json -e 'this.x=1'
加上 --yes 是为了跳过安装确认,避免交互式提示在 CI 里卡住。
为什么这样做:npx 在 5.2 之后会把临时包放到 ~/.npm/_npx,用当前用户身份解包并链接 bin。如果这个目录里混进了 root 所有的文件,后续解包就会失败。chown 是代价最小的修法,比清空整个 ~/.npm 温和,不会把其他项目的缓存一起干掉。
哪里会失效:如果团队用共享 CI 缓存,或者 Docker 镜像里以 root 跑过 npm,~/.npm 的属主问题会反复出现。我遇到过一次在 Docker 里用 root 跑 npx 生成 lock 文件,回到宿主机后所有 npx 命令都报权限错。另一个坑是 npx 的包名和本地已安装的 bin 重名时,它会优先用本地的,版本可能不对,得用 npx -p json@latest json 显式指定。还有,--yes 在 npm 7 以下不认,老版本要改用 --no-install 加手动安装。
你们在 CI 里跑 npx 时,是每次清缓存还是固定用一个非 root 用户?我目前是后者,但镜像层会越滚越大。
0 条评论
还没有评论,写下第一条。