mkdir创建的子目录未继承父目录组,是因为默认由进程主组决定;只有父目录设置了setgid位(权限中为小写s),子目录才会强制继承其组ID且递归生效。

Linux 目录的权限继承不是自动发生的,setgid 是唯一能实现“新建文件/子目录自动继承父目录所属组”的机制,但它对文件和目录的行为不同,且不控制所有权或读写权限本身。
为什么 mkdir 创建的子目录没继承父目录的组?
默认情况下,新创建的目录所属组由进程的 primary group 决定(通常是用户登录组),与父目录无关。只有父目录设置了 setgid 位(即权限中的 s 或 S),内核才会在创建子目录时强制将其组 ID 设为父目录的组 ID。
-
setgid对目录有效:子目录自动继承父目录的group,且自身也带上setgid位(递归生效) -
setgid对普通文件无效:新建文件不会继承父目录组,且其setgid位会被内核自动清除(除非是可执行文件) - 必须用
chgrp先改父目录所属组,再用chmod g+s设置setgid,顺序不能反
chmod g+s 和 chmod 2755 的区别在哪?
两者效果一致,但表达方式不同:g+s 是符号模式,明确表示“给 group 加 setgid 位”;2755 是八进制模式,其中首位 2 就代表 setgid。注意:如果目录已有 rwxr-xr-x(即 755),加 setgid 后显示为 rwxr-sr-x(小写 s);如果 group 没有执行权(如 744),则显示为 rwxr-Sr--(大写 S),此时 setgid 实际不生效。
- 小写
s= group 有x权限 +setgid已启用 - 大写
S= group 无x权限,setgid被设置但被忽略 - 用
ls -ld /path查看,确认是小写s才算真正生效
如何验证 setgid 是否起作用?
不能只看父目录权限,必须实测新建项的所属组。普通用户在该目录下创建内容后,用 ls -l 观察结果:
mkdir /shared chgrp devteam /shared chmod g+s /shared # 切换到非 devteam 成员用户执行: touch /shared/testfile mkdir /shared/testdir ls -ld /shared/testfile /shared/testdir
预期输出中:testdir 的组应为 devteam,且权限含 rwxr-sr-x;testfile 的组通常仍是创建者主组(除非系统启用了 bsdgroups 模式或设置了 umask 002 配合 setgid)。
- 文件是否继承组,取决于
umask和内核策略:Linux 默认不继承,但若umask是002且父目录setgid,新文件组可能碰巧一致(非 guaranteed) - 子目录一定继承,这是 POSIX 明确要求的行为
- 如果测试失败,先检查
mount是否带noexec或nosuid(部分文件系统会禁用setgid)
真正容易被忽略的是:即使 setgid 设置正确,如果用户不属于目标组,chgrp 会失败;而一旦父目录组设错,后续所有继承都无效——所以先确认 getent group devteam 能查到成员,再动手改权限。










