Linux系统下,新建文件项的权限属性通常是0644(-rw-r–r–)、0755(drwxr-xr-x),为什么不是0666、0600呢,umask又是哪来的拦路虎,抹掉进程给文件的授权…🤔
文件项权限是什么
Linux系统下,每个文件项都有一个权限属性,用于限制系统多用户下的安全访问。
如何新建文件项
进程通过以下两组API函数(c语言版)新建文件项、设置权限属性。
/*
* 设置进程的
* file mode creation mask(umask)
*/
mode_t umask(mode_t mask);
/*
* 新建文件项、并通过mode设置权限属性
*/
int open(const char *pathname, \
int flags, \
mode_t mode);
int mkdir(const char *pathname, \
mode_t mode);
为了弄清楚两组API是如何配合使用,直接上代码(c语言版)演示:
我们模拟Shell的touch命令和mkdir命令,函数参数mode设置为0777(drwxrwxrwx)、0666(-rw-rw-rw-),也就是给出了所有的权限,然后通过改变umask,测试新建文件项权限的变化:
int main(){
int fd1,fd2;
/*
* 设置进程的umask为0000
* 新建文件项g1-dir、g1-file
*/
umask( 0000 );
mkdir( "./g1-dir", 0777 );
fd1 = open( "./g1-file", \
O_RDWR|O_CREAT, \
0666 );
close( fd1 );
/*
* 设置进程的umask为更改为0022,
* 其他的保持不变
* 新建文件项g2-dir、g2-file
*/
umask(0022);
mkdir( "./g2-dir", 0777 );
fd2 = open( "./g2-file", \
O_RDWR|O_CREAT, \
0666 );
close( fd2 );
return 0;
}
执行结果:
两次新建文件项g1、g2,通过设置不同的umask,得到了两组不同权限的文件,当使用umask(0022)时,g2组的权限出现了 0644、0755。
从上述执行结果可得出,新建文件项的权限由两组函数决定:
- open、mkdir API的mode参数
- 进程的umask
文件最终权限计算结果:
permission = mode & ~umask
比如:
0644 = 0666 & ~0022
0755 = 0777 & ~0022
看,我们找到 0644、0755这两个神秘数字的来源了,也不是很难嘛😊!
各种默认值
这段代码中有几个常量 0022、0777、0666。没错,这就是系统中的默认值,也是0755、0644的来源。
-
0022:系统默认的umask,后续可以通过函数umask来更改。
-
0777:shell 命令mkdir新建目录,进程调用mkdir函数mode参数的值。
-
0666:shell 命令touch新建文件,进程调用open函数 mode参数的值。
umask的作用及继承
对于开发人员,相信我们对open、mkdir函数比较熟悉,但umask是什么,平时也没用到啊,不用行不行啊🤔
结合上面的示例代码(my_touch.c)我们已经可以看出:
permission = mode & ~umask
- umask用于屏蔽open、mkdir函数参数mode中对应的权限位。例如:umask默认值0022,即禁止组成员用户及其他用户对该文的写权限。
- 子进程继承父进程的umask值,后续通过umask函数修改。
那在写代码新建文件项时,是否需要修改umask?还是那句话,结合业务需要。
- 不修改:继承父进程的umask,mode设为0666、0777,遵守系统调遣。
- 自定义:自定义进程umask,我的文件我做主。
umask(0):关闭umask的影响,权限仅由mode指定,世界清静了。
umask vs chmod
以上两个命令都可以影响、修改文件项的权限属性,但使用场景却各有不同。
umask
1、工作方式:屏蔽权限位。
2、作用对象:新建文件项的默认权限属性。
3、作用范围:严格说是进程级别,但可认为是系统级别或用户级别。
chmod
1、工作方式:设置权限位。
2、作用对象:已存在的文件项权限属性。
3、作用范围:明确指定的文件项。
4、chmod不受umask的影响。
至此0644,0755已不再神秘,umask也由拦路虎变成了破抹布,可以统统丢到垃圾桶了,因为写代码,我选umask(0)。当然咯,非研发人员慎用,大招伤人,容易