umask这个接口在一些程序初始化的时候经常会见到,处于安全性,可以缩小进程落盘文件的权限。
1、linux文件系统的权限规则
文件的默认权限由系统决定(通常是 0666,即所有人可读可写)。
目录的默认权限通常是 0777
(所有人可读可写可执行)。
实际创建的文件 / 目录权限 = 默认权限 & ~mask(按位取反后与默认权限按位与)。
1. 权限的二进制与八进制对应
权限 | 二进制值 | 八进制值 | 符号表示 |
---|---|---|---|
读 (Read) | 100 | 4 | r |
写 (Write) | 010 | 2 | w |
执行 (Execute) | 001 | 1 | x |
无权限 | 000 | 0 | - |
2. 组合权限计算
通过二进制加法或八进制数值相加来组合多个权限:
- 可读可写 =
读 (4)
+写 (2)
=6
(二进制:110
)。 - 可读可执行 =
读 (4)
+执行 (1)
=5
(二进制:101
)。 - 读写执行全权限 =
4 + 2 + 1
=7
(二进制:111
)。
3. 用户组与权限表示
权限分为三个用户组:所有者 (Owner)、组用户 (Group)、其他用户 (Others),每个组对应一个八进制数:
- 文件权限示例:
0644
- 第一位
0
:八进制前缀。 - 第二位
6
(所有者):4 (r) + 2 (w)
= 可读可写。 - 第三位
4
(组用户):4 (r)
= 只读。 - 第四位
4
(其他用户):4 (r)
= 只读。 - 符号表示:
-rw-r--r--
。
- 第一位
- 目录权限示例:
0755
- 所有者:
7 (rwx)
= 读写执行。 - 组用户和其他用户:
5 (r-x)
= 可读可执行。 - 符号表示:
drwxr-xr-x
。
- 所有者:
4. 特殊权限位(SetUID/SetGID/Sticky)
特殊权限 | 二进制值 | 八进制值 | 符号表示(文件) | 符号表示(目录) |
---|---|---|---|---|
SetUID | 1000 | 4 | s 或 S | s 或 S |
SetGID | 0100 | 2 | s 或 S | s 或 S |
Sticky Bit | 0010 | 1 | t 或 T | t 或 T |
SetUID(4)
- 作用:当文件被执行时,临时获得文件所有者的权限。
- 典型场景
/usr/bin/passwd
(修改密码需要访问/etc/shadow
,但普通用户无权限)。
SetGID(2)
-
对 文件:执行时临时获得文件所属组的权限。
-
对 目录:在此目录下创建的文件自动继承目录的组,而非创建者的主组。
-
典型场景:团队共享目录(如
chmod g+s /team_data
)。
Sticky Bit(1)
- 作用:仅文件所有者或 root 能删除该文件,即使其他用户有写权限。
- 典型场景:公共目录
/tmp
(权限通常为1777
,即drwxrwxrwt
)。
2、内核提供的接口
umask
是 Unix/Linux 系统中的一个系统调用,用于设置当前进程创建文件或目录时的默认权限掩码。
基本信息
- 头文件:
#include <sys/stat.h>
- 函数原型:
mode_t umask(mode_t mask);
- 作用:设置当前进程的文件模式创建掩码,并返回之前的掩码值。
- 掩码规则:新文件的实际权限 = 预设权限(如
0666
)按位与~umask
。
权限计算示例
文件类型 | 预设权限 | umask 值 | 实际权限计算 | 最终权限 |
---|---|---|---|---|
文件 | 0666 | 0022 | 0666 & (~0022) = 0644 | -rw-r–r– |
目录 | 0777 | 0022 | 0777 & (~0022) = 0755 | drwxr-xr-x |
使用注意事项
- 永久性:
umask
设置仅对当前进程及其子进程有效,不会影响系统全局设置。 - 默认值:通常系统默认
umask
为0022
(屏蔽其他用户的写权限)。 - 目录与文件差异:目录默认权限通常为
0777
,文件默认权限为0666
(受限于系统限制,文件不能被设置为可执行)。
一些使用技巧
umask(server.umask = umask(0777));
这么写可以安全地获取并保存系统当前的 umask 值,同时避免多线程环境下的竞态条件。