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][+ - =] [权限字符] 文件 / 目录名
"+" 是加上权限,"-" 是减去权限,"=" 是直接设置权限
- [[email protected] tmp]# chmod u-x,g-x,o-x test # 将 ugo 都去掉 x 权限, 等价于 chmod -x test
- [[email protected] 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 值.
- [[email protected] tmp]# umask
- 0022
- [[email protected] 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.
- [[email protected] tmp]$ umask 021
- [[email protected] tmp]$ touch b.txt
- [[email protected] tmp]$ ls -l b.txt
- -rw-r--rw- 1 longshuai longshuai 0 Jun 7 12:02 b.txt
总之计算出后默认都是没有执行权限的.
来源: http://www.bubuko.com/infodetail-3163326.html