Umask 是屏蔽新创建文件和目录权限的掩码,非设置默认权限;它按位取反后与 open()/mkdir() 的 mode 参数运算,只影响新建对象,不改变已有文件或 chmod 行为。

Umask 是什么,它到底控制哪些权限
Umask 不是“设置默认权限”,而是“屏蔽掉哪些权限”。它作用于 open()、mkdir() 等系统调用创建文件/目录时的初始权限(即内核传入的 mode 参数),通过按位取反再与操作,把用户本想设的权限中的一部分“砍掉”。比如进程请求创建文件权限为 0666(rw-rw-rw-),umask 为 0022,最终得到 0644(rw-r--r--)。
关键点:umask 只影响新创建的文件和目录,不影响已有文件;它不改变 chmod 行为,也不影响 setuid/setgid 等特殊位(除非 umask 包含对应位,如 0002 不会清除 sgid,但 0006 会)。
为什么 /etc/profile 和 /etc/bashrc 设置 umask 多数时候不生效
很多文档建议在 /etc/profile 或 /etc/bash.bashrc 中写 umask 002,但这只对交互式登录 shell 生效。SSH 非交互式命令(如 ssh user@host 'touch a')、systemd 服务、cron job、GUI 应用启动的子进程,往往绕过这些文件。更可靠的方式是:
- 系统级统一控制:在
/etc/login.defs中设置UMASK 002(适用于 PAM login,包括 SSH 登录、console 登录) - 确保 PAM 模块启用:检查
/etc/pam.d/login或/etc/pam.d/sshd是否包含session optional pam_umask.so(部分发行版默认已配) - 容器或最小化环境:若无 PAM(如某些 Alpine 容器),需在入口脚本或
/etc/profile.d/下统一 source 的脚本中显式设置umask
umask 002 和 0002 的区别不只是“看起来多一个零”
umask 是八进制,三位或四位都合法,但含义不同:002 等价于 0002,而 022 是三位写法,等价于 0022。真正容易出错的是带前导 0 的四位形式——0002 表示仅屏蔽 group 和 other 的 write 位;但若误写成 22(无前导零),shell 会当作十进制解析,变成八进制 026,结果完全不可控。
安全实践建议:
- 始终用三位或四位八进制写法,显式加前导
0:如umask 002、umask 027 - 避免使用符号模式(如
umask g-w,o-w),它依赖 shell 实现,bash 支持,dash/sh 不支持 - 验证是否生效:执行
umask查看当前值,再touch test && ls -l test观察实际权限
目录和文件的默认权限天生不同,umask 无法让它们一致
这是最常被忽略的前提:内核对文件和目录的初始权限硬编码不同。普通文件默认是 0666,目录默认是 0777。因此即使 umask 是 002,新建文件是 0664(rw-rw-r--),新建目录却是 0775(rwxrwxr-x)。你无法靠 umask 让文件也带 x 位——那是危险且违反 POSIX 的。
如果业务真需要可执行文件(如部署脚本),必须显式 chmod +x;若需强制所有新建目录带 sgid(继承父目录 group),得结合 chmod g+s 父目录 + umask 保证 group 写权限(如 umask 002),而非指望 umask 自己加 bit。


















