打开网易新闻 查看精彩图片

凌晨2点,Jeremy的终端弹出EACCES: permission denied时,他以为只是少了sudo。三小时后,整个团队发现问题的根因完全不在代码里——而在三个月前某次调试留下的文件归属记录。

Claude Code在Linux多用户环境下的权限架构,比大多数AI工具都更敏感。它不只是在"运行",而是在持续读写日志、缓存和配置。一旦这些文件的属主和当前用户错位,拒绝访问就成了必然。

症状:不是权限不够,是文件"认错了主人"

症状:不是权限不够,是文件"认错了主人"

Jeremy的报错信息很干净:syscall "open"失败,errno -13。按常规思路,他检查了~/.claude目录的权限——700,属主admincostplus。问题是他自己就是jeremy,不是admincostplus。

真正诡异的是,这个目录明明在jeremy的家目录下,属主却是另一个账户。Claude Code尝试往~/.claude/debug写日志时,系统直接拦住了。

时间线倒推:三个月前,admincostplus账号曾在jeremy的家目录下运行过Claude Code。当时为了排查问题,用了root权限或者切换用户的方式启动。结果创建的文件和子目录,全部带上了admincostplus的属主标记。

jeremy对自己的家目录有读权限,但对admincostplus创建的文件没有写权限。Claude Code的日志模块一启动就崩溃,整个程序跟着挂掉。

--dangerously-skip-permissions跳过检查?没用。这个flag只是跳过Claude自己的权限校验,真正的EACCES来自操作系统内核。

诊断:三层权限叠加的"幽灵文件"

诊断:三层权限叠加的"幽灵文件"

Linux权限问题的麻烦在于,表面症状和根因往往隔了好几层。jeremy遇到的场景,实际上是三层叠加:

打开网易新闻 查看精彩图片

第一层是用户隔离。Linux的家目录设计假设每个用户独立运作,Claude Code却需要在多账户间共享配置和对话历史。这个张力从架构层面就存在。

第二层是历史遗留。admincostplus之前运行产生的文件,成了jeremy家目录里的"钉子户"。ls -la /home/jeremy/.claude/debug/显示drwx------ 2 admincostplus admincostplus——jeremy连进都进不去。

第三层是Claude Code的写入习惯。它不像传统CLI工具那样只读配置,而是持续追加日志、更新状态文件。这意味着即使jeremy能"看到"目录,只要写操作被拒绝,启动流程就会中断。

常见的chmod 777方案为什么被作者明确否定?因为它破坏了审计追踪,让后续排查更困难,而且在生产环境属于安全红线。

方案:用setgid位做"权限遗传"

方案:用setgid位做"权限遗传"

作者给出的生产级脚本,核心思路是建立一个共享组claudeusers,让文件归属从"用户级"降到"组级",同时用setgid位(chmod 2775中的2)确保新创建的文件自动继承组属主。

脚本分三步走:

第一步建组加人。getent检查claudeusers是否存在,不存在就groupadd创建。然后用usermod -a -G把jeremy和admincostplus都加进去。-a参数防止覆盖用户已有的其他组归属,这是生产环境的安全习惯。

第二步创建共享目录/opt/claude-shared,用jeremy作为属主、claudeusers作为属组。chmod 2775里的2就是setgid位,作用类似于目录的"基因标记"——任何在里面创建的文件,自动带上claudeusers组身份,而不是创建者的主组。

第三步处理四个关键目录的迁移:.claude、.claude-code、.config/claude-code、.local/share/claude-code。脚本用rsync把jeremy家目录下的内容同步到共享位置,然后给admincostplus的家目录建立符号链接指向共享位置。

打开网易新闻 查看精彩图片

符号链接的设计很精巧。admincostplus以后运行Claude Code时,读写操作实际发生在/opt/claude-shared,但路径看起来还是原来的~/.claude。应用程序无感知,用户也无感知。

备份逻辑也考虑到了:如果admincostplus的家目录里已经有同名目录且不是符号链接,脚本会把它重命名为.bak-时间戳,防止数据丢失。

执行:为什么必须用root

执行:为什么必须用root

整个脚本需要sudo或root执行,原因很实际:修改其他用户的家目录内容、创建系统级共享目录、修改用户组归属,这些操作都超出了普通用户的权限边界。

作者特意在注释里写明"Run as: sudo bash this-script.sh",因为实际部署中,很多工程师会习惯性地复制粘贴脚本内容,忽略执行身份要求。

一个细节:脚本用了getent passwd "$MASTER_USER" | cut -d: -f6来获取家目录路径,而不是硬编码/home/jeremy。这在用户家目录被自定义到/data或/nfs等位置的环境中能救命。

另一个细节:rsync用了--delete参数。这意味着如果共享目录里已经有内容,会被jeremy家目录的版本覆盖。作者假设jeremy是"主用户",admincostplus是"辅助账户",这个假设需要在执行前确认。

如果实际情况相反——admincostplus的配置更完整——就需要交换MASTER_USER和ADMIN_USER的值,或者手动合并配置。

这套方案的价值不在于解决了一个具体的EACCES错误,而在于提供了一种可复用的多用户AI工具权限模型。Claude Code不是第一个遇到这个问题的工具,也不会是最后一个。

当AI编程助手从个人玩具变成团队协作基础设施,Linux权限架构的古老智慧——用户、组、setgid、符号链接——反而成了最可靠的解决方案。没有新发明,只有对现有机制的精确组合。

你的团队里,有多少个jeremy和admincostplus在共用服务器跑Claude Code?他们的~/.claude目录,现在属主是谁?