umask这个接口在一些程序初始化的时候经常会见到,处于安全性,可以缩小进程落盘文件的权限。
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)。
内核提供的接口
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 值,同时避免多线程环境下的竞态条件。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论