深入理解文件权限

时间:2021-07-24 16:45:19

## 查看文件、目录和设备的权限

例如,本人某目录下有如下文件:

$ ls -l 
total 68 
-rw-rw-r-- 1 craftor craftor 50 2013-06-02 09:31 file1 
-rw-rw-r-- 1 craftor craftor 28 2013-06-03 15:40 file2 
-rwxrwxr-x 1 craftor craftor 4881 2013-05-20 17:23 myprog 
-rw-rw-r-- 1 craftor craftor 287 2013-05-20 17:23 myprog.c 
drwxrwxr-x 2 craftor craftor 4096 2013-06-20 14:20 test1 
drwxrwxr-x 2 craftor craftor 4096 2013-06-22 13:40 test2 
$
输出结果的第一个字段是描述文件和目录的权限的码。这个字段的第一个字符代表的对象的类型:

- -代表文件
- d代表目录
- l代表链接
- c代表字符型设备
- b代表块设备
- n代表网络设备

之后有3组三字符的码。每一组三字符码表示三重访问权限:

- r代表对象是可读的
- w代表对象是可写的
- x代表对象是可执行的

如果没有某种权限,在该权限位会出现单破折线。这3组三字码分别对应对象的3个安全级别:

- 对象的属主
- 对象的属组
- 系统其他用户

如下图:

-rwxrwxr-x 1 craftor craftor 4882 2013-06-22 13:40 myprog
| | |
| | +----------其他用户的权限(r-x)
| +-------------属组用户的权限(rwx)
+----------------文件属主的权限(rwx)

## 默认文件权限

你可能会问这些文件权限从何而来,答案是umask。umask命令用来设置用户创建文件和目录的默认权限:

$ toucn test 
$ ls -la test 
-rw-rw-r-- 1 craftor craftor 0 Jun 25 10:50 test

touch命令用分配给我的用户账号的默认权限创建了这个文件。umask命令可以显示和设置这个默认权限:

$ umask 
0002

其实,很容易理解umask的值。先看一下Linux权限码:

=======================================================
权 限 二进制值 八进制值 描 述
-------------------------------------------------------
--- 000 0 没有任何权限
--x 001 1 只有执行权限
-w- 010 2 只有写入权限
-wx 011 3 有写入和执行权限
r-- 100 4 只有读取权限
r-x 101 5 有读取和执行权限
rw- 110 6 有读取和写入权限
rwx 111 7 有全部权限
=======================================================

如果一个文件的权限码是rw-rw-rw-,那么对应的八进制值就是666,即所有人都可以读取和写入。
umask是个掩码。它屏蔽掉了不想授予该安全级别的权限。umask值会从对象的全权限值中减掉,对文件来说,全权限值是666;而对于目录来说,是777。所以,上面的例子中,文件一开始的权限是666,然后经umask值002作用后,变成了664。

可以使用umask命令为默认umask设置一个新值:

$ umask 026 
$ touch test2 
$ ls -la test2 
-rw-r----- 1 craftor craftor 0 Jun 25 15:14 test2

在把umask值设成026后,默认的文件权限变成了640,因些新的文件在对属组成员来说是只读的,而系统里的其他成员没有任何权限。umask同样也会作用在创建目录上。

$ mkdir newdir 
$ ls -l 
drwxr-x--x 2 craftor craftor 4096 Jun 25 15:16 newdir

由于目录的默认权限是777,umask作用后生成的目录权限是777减支026,留下751作为目录权限。

## 改变权限

使用chmod命令可以改变文件或文件夹权限。格式为:

chmod options mode file

mode参数后可跟八进制数模式或符号模式来设置安全性。八进制模式设置非常直接,直接用期望赋予的标准的3位八进制权限码:
$ chmod 760 newfile 
$ ls -l newfile 
-rwxrw---- 1 craftor craftor 0 Jun 25 15:19 newfile

符号模式的权限就没这么简单了。与通常用到的3组三字符权限字符不同,chmod命令用了另外一种实现。下面是在符号模式下指定权限的格式:

[ugoa...][+-=][rwxXstugo...]

很有意思,不是吗?第一组字符定义了权限作用对象:

- u代表用户
- g代表组
- o代表其他用户
- a代表所有人

下一步,后面跟着的的符号是表示你是想在现有的权限基础增加权限(+),还是在现有权限基础上移除权限(-),还是将权限设置成后面的值(=)。
最后,第3个符号代表作用到设置上的权限。你会发现,这个值要比rwx多,额外的设置有以下几项:

- X: 如果对象是目录或者它已有执行权限,赋予执行权限
- s: 运行时重新设置UID或者GID
- t: 保留文件或目录
- u: 将权限设置为跟属主一样
- g: 将权限设置为跟属组一样
- o: 将权限设置为跟其他用户一样

例如:

$ chmod o+r newfile 
$ ls -l newfile 
-rwxrw-r-- 1 craftor craftor 0 Jun 25 15:31 newfile

不管其他用户在这一安全级别之前都有什么权限,o+r给这一级别添加了读取权限。
$ chmod u-x newfile 
$ ls -l newfile 
-rw-rw-r-- 1 craftor craftor 0 Jun 25 15:31 newfile

u-x移除了属主已有的执行权限。

如果是对于文件夹,可以加上-R参数,对所有文件夹下的文件和目录也起作用。

## 改变所属关系

有时候你需要改变文件的属主,比如有人离职或者开发人员创建了一个在产品环境中运行时需要归属在系统账户下的应用。Linux提供了两个命令来完成这个功能:chown命令用来改变文件的属主,chgrp命令用来改变文件的默认属组。
chown命令格式如下:

chown options owner[.group] file

可用登录名或UID来指定文件的新属主:

# chwon dan newfile 
# ls -l newfile 
-rw-rw-r-- 1 dan craftor 0 Jun 25 15:31 newfile


非常简单,chown命令也支持同时改变文件的属主和属组:

# chwon dan.shared newfile 
# ls -l newfile 
-rw-rw-r-- 1 dan shared 0 Jun 25 15:31 newfile


如果你不嫌麻烦,可以这么改变一个文件的默认属组:
# chown .rich newfile 
# ls -l newfile 
-rw-rw-r-- 1 dan rich 0 Jun 25 15:31 newfile

最后,如果你的Linux系统采用和用户登录名匹配的组名,你可以只用一个条目就改变二者:
# chown test. newfile 
# ls -l newfile 
-rw-rw-r-- 1 test test 0 Jun 25 15:31 newfile

同样,对于chown命令,-R可以递归地改变子目录和文件的所属关系,-h参数可以改变该文件的所有符号链接文件的所属关系。

> 说明:只有root用户能够改文件属主。任何属主都可以改变文件的属组,但前提是属主必须是源和目标属组的成员。

chgrp命令可以很方便地更改文件或目录的默认属组:

$ chgrp shared newfile 
$ ls -l new file 
-rw-rw-r-- 1 test shared 0 Jun 25 15:31 newfile

现在shared组的任意用户都可以写这个文件了。