你的 npm 全局 prefix 指向了 root 拥有的目录。把 prefix 改到自己拥有的目录(npm config set prefix ~/.npm-global)并把它的 bin 加进 PATH,或者用 Node 版本管理器装 Node。别用 sudo——它会在 npm 缓存里留下 root 拥有的文件,让后续安装以更难查的方式失败。
npm ERR! code EACCES
npm ERR! syscall mkdir
npm ERR! path /usr/local/lib/node_modules/@deepseek-ai
npm ERR! errno -13
npm 在往一个你的用户不拥有的目录写。这和 @deepseek-ai/dsh 一点关系都没有——这是你 npm 安装本身的
状态,在你修好之前,任何全局包都会这样失败。
确认成因
npm config get prefix如果打印 /usr/local、/usr 或别的系统路径,说明 npm 的全局目录在你的 home 之外,写它需要提权。
不会制造新问题的修法
把 prefix 指到你自己拥有的目录:
mkdir -p ~/.npm-global
npm config set prefix ~/.npm-global然后把它的 bin 加进 PATH——现代 macOS 写进 ~/.zshrc,多数 Linux 写进 ~/.bashrc:
export PATH="$HOME/.npm-global/bin:$PATH"开一个新 shell(已经开着的不会重读配置),重新安装:
npm install -g @deepseek-ai/dsh
dsh --help为什么不该用 sudo
sudo npm install -g @deepseek-ai/dsh 看起来会成功。破坏要到后面才显形。
以 root 身份安装,会往你的 npm 缓存和全局目录里都写入 root 拥有的文件。下一次你不带 sudo 装
任何东西时,npm 撞上一个它写不了的缓存条目然后失败——而报错通常既不提权限、也不提当初那次 sudo。
于是人们再次伸手去够 sudo,问题复利。
如果你已经这么干过,把缓存要回来:
sudo chown -R "$(whoami)" ~/.npmmacOS 上用 Homebrew 装的 Node,可能还需要:
sudo chown -R "$(whoami)" /usr/local/lib/node_modules然后按上面把 prefix 改掉,从此不再需要 sudo。
结构性的修法:版本管理器
如果你用 Node 不止为这一个工具,改用 nvm、fnm 或 volta 装它。每个 Node 版本都住在你的 home 目录
下、各带一套全局包目录,全局安装报 EACCES 这件事就变得不可能了。
# 用 fnm
fnm install --lts
fnm use --lts
npm install -g @deepseek-ai/dsh有个代价要知道:每个 Node 版本的全局目录是分开的,所以在 Node 20 下装的包,Node 22 下没有。如果
升级 Node 之后 dsh 不见了,原因就在这——见
dsh: command not found。
不安装的那条路
捋这些的同时你并没有被卡住:
npx @deepseek-ai/dsh webnpx 解析并运行这个包,不往任何全局目录写。启动慢一点,零配置,不涉及权限。
常见问题
为什么不直接用 sudo?
它看起来能用,但会往 npm 缓存和全局目录里写入 root 拥有的文件。之后任何一次不带 sudo 的安装都会撞上它动不了的文件,而报错通常完全指不到真正的成因。
非要全局安装吗?
不必。npx @deepseek-ai/dsh web 不装任何全局包,也从不碰系统目录。
改 prefix 和用版本管理器,哪个更好?
只要你还算常用 Node,就用版本管理器——它从结构上消灭了这整类问题,还能并存多个 Node 版本。改 prefix 是更小、更快的那个修法。