Linux基础知识:文件权限管理以及umask
1 文件/目录的权限
1.1 文件的权限
每个文件都有其所有者(u:user)、所属组(g:group)和其他人(o:other)对它的操作权限,a:all则同时代表这3者。权限包括读(r:read)、写(w:write)、执行(x:execute)。在不同类型的文件上读、写、执行权限的体现有所不同,所以目录权限和普通文件权限要区分开来。
在普通文件上:
r:可读,可以使用类似cat等命令查看文件内容;读是文件的最基本权限,没有读权限,普通文件的一切操作行为都被限制。
w:可写,可以编辑此文件;
x:可执行,表示文件可由特定的解释器解释并运行。可以理解为windows中的可执行程序或批处理脚本,双击就能运行起来的文件。
在目录上:
r:可以对目录执行ls以列出目录内的所有文件;读是文件的最基本权限,没有读权限,目录的一切操作行为都被限制。
w:可以在此目录创建或删除文件/子目录;
x:可进入此目录,可使用ls -l查看文件的详细信息。可以理解为windows中双击就进入目录的动作。
如果目录没有x权限,其他人将无法查看目录内文件属性(只能查看到文件类型和文件名,至于为什么,见后文),所以一般目录都要有x权限。而如果只有执行却没有读权限,则权限拒绝。
一般来说,普通文件的默认权限是644(没有执行权限),目录的默认权限是755(必须有执行权限,否则进不去),链接文件的权限是777。当然,默认文件的权限设置方法是可以通过umask值来改变的。
1.2 权限的表示方式
权限的模式有两种体现:数字体现方式和字符体现方式。
权限的数字表示:"-"代表没有权限,用0表示。
r-----4
w-----2
x-----1
例如:rwx rw- r--对应的数字权限是764,732代表的权限数值表示为rwx -wx -w-。
1.3 chmod修改权限
能够修改权限的人只有文件所有者和超级管理员。
chmod [OPTION]... MODE[,MODE]... FILE... chmod [OPTION]... num_mode FILE... chmod [OPTION]... --reference=RFILE FILE... 选项说明: --reference=RFILE:引用某文件的权限作为权限值 -R:递归修改,只对当前已存在的文件有效
(1). 使用数值方式修改权限
shell> chmod 755 /tmp/a.txt
(2). 使用字符方式修改权限
由于权限属性附在文件所有者、所属组和其它上,它们三者都有独立的权限位,所有者使用字母"u"表示,所属组使用"g"来表示,其他使用"o"来表示,而字母"a"同时表示它们三者。所以使用字符方式修改权限时,需要指定操作谁的权限。
chmod [ugoa][+ - =] [权限字符] 文件/目录名
"+"是加上权限,"-"是减去权限,"="是直接设置权限
[root@xuexi tmp]# chmod u-x,g-x,o-x test # 将ugo都去掉x权限,等价于chmod -x test [root@xuexi tmp]# chmod a+x test # 为ugo都加上x权限,等价于chmod +x test
1.4 chgrp
更改文件和目录的所属组,要求组已经存在。
注意,对于链接文件而言,修改组的作用对象是链接的源文件,而非链接文件本身。
chgrp [OPTION]... GROUP FILE... chgrp [OPTION]... --reference=RFILE FILE.. 选项说明: -R:递归修改 --reference=dest_file file_list:引用某文件的group作为文件列表的组,即将file文件列表的组改为dest_file的组
1.5 chown
chown可以修改文件所有者和所属组。
注意,对于链接文件而言,默认不会穿过链接修改源文件,而是直接修改链接文件本身,这和chgrp的默认是不一样的。
chown [OPTION]... [OWNER][:[GROUP]] FILE... chown [OPTION]... [OWNER][.[GROUP]] FILE... chown [OPTION]... --reference=RFILE FILE... 选项说明: --from=CURRENT_OWNER:CURRENT_GROUP:只修改当前所有者或所属组为此处指定的值的文件 --reference=RFILE:引用某文件的所有者和所属组的值作为新的所有者和所属组 -R:递归修改。注意,当指定-R时,且同时指定下面某一个选项时对链接文件有不同的行为 -H:如果chown的文件参数是一个链接到目录的链接文件,则穿过此链接文件修改其源目录的所有者和所属组 -L:目录中遇到的所有链接文件都穿越过去,修改它们的源文件的所有者和所属组 -P:不进行任何穿越,只修改链接文件本身的所有者和所属组。(这是默认值) 这3项若同时指定多项时,则最后一项生效
chown指定所有者和所属组的方式有两种,使用冒号和点。
shell> chown root.root test shell> chown root:root test shell> chown root test # 只修改所有者 shell> chown :root test # 自修改组 shell> chown .root test
2 实现权限的本质
涉及文件系统的知识点,若不理解,可以先看看文件系统的内容。此处是以ext4文件系统为例的,在其他文件系统上结果可能会有些不一样(centos 7上使用xfs文件系统时结果可能就不一样),但本质是一样的。
不同的权限表示对文件具有不同能力,如读写执行(rwx)权限,但是它是怎么实现的呢?描述文件权限的数据放在哪里呢?
首先,权限的元数据放在inode中,严格地说是放在inode table中,因为每个块组的所有inode组成一个inode table。在inode table中使用一列来存放数字型的权限,比如某文件的权限为644。每次用户要对文件进行操作时系统都会先查看权限,确认该用户是否有对应的权限来执行操作。当然,inode table一般都已经加载到内存中,所以每次查询权限的资源消耗是非常小的。
无论是读、写还是执行权限,所体现出来的能力究其本质都是因为它作用在对应文件的data block上。
2.1 读权限(r)
对普通文件具有读权限表示的是具有读取该文件内容的能力,对目录具有读权限表示具有浏览该目录中文件或子目录的能力。其本质都是具有读取其data block的能力。
对于普通文件而言,能够读取文件的data block,而普通文件的data block存储的直接就是数据本身, 所以对普通文件具有读权限表示能够读取文件内容。
对于目录文件而言,能够读取目录的data block,而目录文件的data block存储的内容包括但不限于:目录中文件的inode号(并非直接存储,而是存储指向inode table中该inode号的指针)以及这些文件的文件类型、文件名。所以能够读取目录的data block表示仅能获取到这些信息。
目录的data block内容示例如下:
例如:
shell> mkdir -p /mydata/data/testdir/subdir # 创建testdir测试目录和其子目录subdir shell> touch /mydata/data/testdir/a.log # 再在testdir下创建一个普通文件 shell> chmod 754 /mydata/data/testdir # 将testdir设置为对其他人只有读权限
然后切换到普通用户查看testdir目录的内容。
shell> su - wangwu shell> ll -ai /mydata/data/testdir/ ls: cannot access /mydata/data/testdir/..: Permission denied ls: cannot access /mydata/data/testdir/a.log: Permission denied ls: cannot access /mydata/data/testdir/subdir: Permission denied ls: cannot access /mydata/data/testdir/.: Permission denied total 0 ? d????????? ? ? ? ? ? . ? d????????? ? ? ? ? ? .. ? -????????? ? ? ? ? ? a.log ? d????????? ? ? ? ? ? subdir
从结果中看出,testdir下的文件名和文件类型是能够读取的,但是其他属性都不能读取到。而且也读取不到inode号,因为它并没有直接存储inode号,而是存储了指向Inode号的指针,要定位到指针的指向需要执行权限。
2.2 执行权限(x)
执行权限表示的是能够执行。如何执行?执行这个词不是很好解释,可以简单的类比Windows中的双击行为。例如对目录双击就能进入到目录,对批处理文件双击就能运行(有专门的解释器解释),对可执行程序双击就能运行等。
当然,读权限是文件的最基本权限,执行权限能正常运行必须得配有读权限。
对目录有执行权限,表示可以通过目录的data block中指向文件inode号的指针定位到inode table中该文件的inode信息,所以可以显示出这些文件的全部属性信息。
2.3 写权限(w)
写权限很简单,就是能够将数据写入分配到的data block。
对目录文件具有写权限,表示能够创建和删除文件。目录的写操作实质是能够在目录的data block中创建或删除关于待操作文件的记录。它要求对目录具有执行权限,因为无论是创建还是删除其内文件,都需要将其data block中inode号和inode table中的inode信息关联或删除。
对普通文件具有写权限,实质是能够改写该文件的data block。
还是要说明的是,对文件有写权限不代表能够删除该文件,因为删除文件是要在目录的data block中删除该文件的记录,也就是说删除权限是在目录中定义的。
所以,对目录文件和普通文件而言,读、写、执行权限它们的依赖关系如下图所示。
3 umask说明
umask值用于设置用户在创建文件时的默认权限。对于root用户(实际上是UID小于200的user),系统默认的umask值是022;对于普通用户和系统用户,系统默认的umask值是002。
默认它们的设置是写在/etc/profile和/etc/bashrc两个环境配置文件中。
shell> grep -C 5 -R 'umask 002' /etc | grep 'umask 022' /etc/bashrc- umask 022 /etc/csh.cshrc- umask 022 /etc/profile- umask 022
相关设置项如下:
if [ $UID -gt 199 ] && [ "`id -gn`" = "`id -un`" ]; then umask 002 else umask 022 fi
执行umask命令可以查看当前用户的umask值。
[root@xuexi tmp]# umask 0022
[longshuai@xuexi tmp]$ umask 0002
执行umask num可以临时修改umask值为num,但这是临时的,要永久有效,需要写入到环境配置文件中,至于写入到/etc/profile、/etc/bashrc、~/.bashrc还是~/.bash_profile中,看你自己的需求了。不过一般来说,不会去永久修改umask值,只会在特殊条件下临时修改下umask值。
umask是如何决定创建文件的默认权限的呢?
如果创建的是目录,则使用777-umask值,如root的umask=022,则root创建目录时该目录的默认权限为777-022=755,而普通用户创建目录时,权限为777-002=775.
如果创建的是普通文件,在Linux中,深入贯彻了一点:文件默认不应该有执行权限,否则是危险的。所以在计算时,可能会和想象中的结果不一样。如果umask的三位都为偶数,则直接使用666去减掉umask值,因为6减去一个偶数还是偶数,任何位都不可能会有执行权限。如root创建普通文件时默认权限为666-022=644,而普通用户创建普通文件时默认权限为666-002=664。
如果umask值某一位为奇数,则666减去umask值后再在奇数位上加1。如umask=021时,创建文件时默认权限为666-021=645,在奇数位上加1,则为646。
[longshuai@xuexi tmp]$ umask 021 [longshuai@xuexi tmp]$ touch b.txt [longshuai@xuexi tmp]$ ls -l b.txt -rw-r--rw- 1 longshuai longshuai 0 Jun 7 12:02 b.txt
总之计算出后默认都是没有执行权限的。