DEBUG.WIKI
V.PS:让项目靠近用户,亚太、欧洲、北美 KVM VPS
IPPeak:从目标地区访问网页,住宅代理、SEO 监测、广告验证
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国

Linux chown 改了符号链接目标,链接所有者仍未变化

GNU chown 非递归操作默认修改符号链接目标。用 stat 分别确认两者属性,使用 chown -h 修改链接,并单独处理此前误改目标的恢复。

对符号链接执行 chown appuser ./current 后,current 仍显示原来的所有者,链接指向的目录却换了所有者。这种情况下,重复执行同一条命令只会继续操作目标对象。

在 Linux 上使用 GNU chown、且没有递归选项时,默认行为是跟随符号链接修改目标。要修改链接对象本身,需要 -h,也就是 --no-dereference。本文只处理单个链接,不把这一规则直接套进递归遍历、其他系统的 chown 或容器内外 UID 映射问题。

分别记录链接和目标的所有者

操作前先确认路径是链接,以及它指向哪里。以下 ./current 是示例路径,末尾不加 /;添加尾部斜杠会影响路径解析,不能当成同一个检查对象。

readlink -- ./current
stat -c 'link: uid=%u gid=%g mode=%a type=%F name=%n' -- ./current
stat -L -c 'target: uid=%u gid=%g mode=%a type=%F name=%n' -- ./current

GNU stat 不加 -L 时查看链接本身,加 -L 时查看目标。数字 UID、GID 便于前后对照,不会把用户名解析差异误认为文件属性变化。保留两份输出与链接文本;如果目标检查报错,先处理不存在或不可访问的路径,不要直接进入修改步骤。

readlink 输出相对路径时,它相对于链接所在目录解析。不要从另一个工作目录直接拿这个字符串作为待修改目标。检查与修改期间还应避免部署程序或其他进程替换这个链接;先前记录不能保证之后同一路径仍对应同一个对象。

只修改链接本身

确认需求确实是链接所有者,并将 appuser、appgroup 换成环境中存在且已获准使用的用户和组,再执行:

sudo chown -h -- appuser:appgroup ./current

这里用 sudo 表示需要相应权限的管理操作;已经具备所需权限时不必额外使用。-h 决定修改链接对象,-- 结束选项解析。命令没有 -R,不会把单链接修改扩展成整个目录树操作。

如果只需要改用户、保留链接原来的组,使用:

sudo chown -h -- appuser ./current

不要在用户名后随手加一个冒号。appuser: 还会把组改成该用户的登录组,与只写 appuser 不同。

修改后重新运行前面的三条检查,确认链接 UID、GID 符合要求,链接文本未变,并且目标 UID、GID 与此次操作前的记录一致。命令成功返回只是一个检查点,不能代替分清链接和目标的前后对照。

已经误改目标时,单加 -h 不会撤销

如果之前的默认 chown 已经改变目标,再运行 chown -h 只会修正链接,不会恢复目标。恢复目标必须依赖修改前的可靠记录,不能根据链接原来的所有者推测目标也属于同一用户,更不能统一改回 root。

对于链接本身,可将记录的数字代入以下形式。OLD_LINK_UID、OLD_LINK_GID 是需要替换的占位值,不是建议创建的用户和组:

sudo chown -h -- OLD_LINK_UID:OLD_LINK_GID ./current

若目标也要恢复,先确认它的真实路径及修改前的 UID、GID,再单独恢复该对象。不要加入递归选项扩大恢复范围。chown 可能受系统规则影响而清除 set-user-ID 或 set-group-ID 位,因此只恢复 UID、GID 不能宣称所有元数据都已复原;应根据原记录复核权限位,缺少记录时不要猜测性补回。

所有者改对后仍访问失败

chown 调整的是用户和组归属,不负责修复断开的链接,也不直接修改普通读写执行权限位。访问目标失败时,需要继续检查目标路径及相关目录权限;不要通过反复修改链接所有者或放宽整个目录树权限来试错。

如果带 -h 后检查仍不一致,先确认实际执行的是预期的 GNU chown、查看的是同一路径和同一个运行环境,并检查完整错误输出及是否有并发替换。上述规则依赖系统支持修改链接所有者;不能仅凭终端中的一条状态文字,判断链接和目标都已按要求修改。