Linux文件的权限与属性

时间:2021-08-02 23:52:33

  由于以前学习Linux的时候没有做比较全面的总结笔记,而且平时大部分工作都在windows上进行,所以关于Linux的一些知识点有所遗忘。近期难得空闲,翻阅书籍,学习《鸟哥的Linux私房菜》,重温Linux知识,借此机会想把Linux的相关知识做一个总结笔记。首先要总结的是Linux文件相关知识——权限与属性。注意,这不是Linux入门,这是学习笔记,入门推荐《鸟哥的Linux私房菜》,讲得很详细。

  讲解Linux文件的权限与属性,自然绕不开ls命令啦。在Linux中,我们可以通过命令ll(即ls -l)查看当前目录下文件的权限与属性的详情列表:

Linux文件的权限与属性

输出结果中有7个信息列,从左到右分别是:文件类型+权限、文件连接数、文件属主、文件属组、文件大小、文件最后修改时间、文件名称。好了,下面开始详细介绍每个信息点。

一、文件权限

  首先要介绍的是文件权限,这在Linux中是很重要的。

1. 基本权限:

  Linux是一个多用户的操作系统,对于每一个文件而言,用户的类型有三种:文件属主,即文件的创建者;文件属组,即文件所属的用户群组;其他用户。对应的,有三种用户类型对于这个文件的权限,每种用户类型的权限都有:读(r)、写(w)、执行(x)三种权限。在上面的截图的第一列信息中有十个字符,其中第一个字符表示的是文件类型,后面的9个字符从左到右分别表示属主、属组和其他用户对于文件的rwx三种权限的占位符,某个位置上有对应英文字母表示有相应权限,如果是“-”则表示没有相应权限。例如,最后一个文件“yzz”,属主和属组用户对文件有读写权限,而其他用户则只有读权限。

  修改文件权限可以通过chmod指令来实现,其中权限可以通过字符表示也可以通过数字来表示,比较简单,这里就不再过多说明,使用上图“myfile”这个文件来实验,直接看实验截图,注意观察文件各个权限位的变化:

Linux文件的权限与属性

(u表示属主,g表示属组,o表示其他用户)

  如果想要修改文件属主、属组可以通过chown和chgrp来实现(注意观察第三列和第四列信息的变化):

Linux文件的权限与属性

2. 特殊权限:

(1)Set UID:

  当s这个标志出现在文件属主的x权限位上时,此时就被称为Set UID,简称为SUID的特殊权限。SUID的限制与功能如下:

<1>SUID权限仅对二进制程式有效;

<2>执行者对该程式需要具有x的可执行权限;

<3>本权限仅在执行该程式的过程中有效;

<4>执行者将具有该程式拥有者的权限。

以下面两个文件举例说明:

Linux文件的权限与属性

从上图可以看出,一般用户对于“/etc/shadow”这个文件是没有任何权限的,只有root可以对这个文件进行修改。但是用户却可以使用passwd这个指令,也就是执行“/usr/bin/passwd”这个文件通过对“/etc/shadow”进行修改来修改自己的密码。原因就是因为“/usr/bin/passwd”这个文件具有SUID的特殊权限,一般用户执行这个文件的过程中暂时拥有这个文件的拥有者root的权限,所以也就可以对“/etc/shadow”这个文件进行修改了。

(2)Set GID:

  当s这个标志出现在文件属组的x权限位上时,称为Set GID,简称SGID。SGID不仅对二进制程式有效,对于目录也是有效的。

  当SGID设置在二进制程式上时,与SUID类似地,文件的执行者在执行过程中将暂时拥有文件属组的权限,这个在Linux中有以下两个文件可作为例子:

Linux文件的权限与属性

  当SGID设置在目录上时,具有以下特殊功能:

<1>对目录具有r与x权限的用户能进入目录。

<2>使用者在此目录下的有效群组将会变成该目录的群组。

<3>对目录具有w权限的用户,在此目录下创建文件时,新文件的群组与此目录群组相同。

当某个用户组的用户想要在某个目录下共享资源的时候,SGID的第三个功能就能派上用场了。

(3)Sticky Bit:

  Sticky Bit简称SBIT,目前只针对目录有效。当某个目录被设置了SBIT之后,目录的其他用户的x权限位将出现t标志,具有w和x权限的用户在该目录下创建的文件或目录,只有自己和root才有权限删除。/tmp就是这样的目录:

Linux文件的权限与属性

(4)SUID/SGID/SBIT设置:

  特殊权限的设置也是使用chmod这个命令,特殊权限的表示同样可以使用字符形式也可以使用数字,使用数字时在代表rwx基本权限三个数字前面再加一个数字就可以了,其中4为SUID,2为SGID,1为SBIT,设置实验如下:

Linux文件的权限与属性

输出结果最后一行,S、T为大写时表示对应特殊权限为空,原因是对应用户没有x执行权限。

3. 默认权限:

  在Linux中,新建的文件或目录的默认权限是由umask决定的,那么这个umask到底是什么呢?我们先来查看一下:

Linux文件的权限与属性

这里有两种查询方式,第二种我们很容易明白,那第一种打印出来的那四个数字有什么意义呢?它们分别代表特殊权限(SUID/SGID/SBIT)、文件属主(u)、文件属组(g)、其他用户(o)的权限!

  那新建文件或目录的默认权限是怎么计算的呢?我们知道新建文件默认是没有执行权限的,所以它的完整权限是rw-rw-rw-,用数字表示就是666,而新建目录默认是有执行权限的,所以它的完整权限是rwxrwxrwx,用数字表示就是777。新建文件或目录的默认权限就是使用这个三位数字表示的完整权限分别减去umask指令查询出来的后面三位数字,所以当umask是0002的时候,新建文件的默认权限就是664,即rw-rw-r--,新建文件夹的默认权限就是775,即rwxrwxr-x,也就是说umask -S打印出来的结果其实是新建目录的默认权限,新建文件的默认权限要在umask -S结果的基础上减去所有用户的x执行权限。不信我们可以新建文件和目录来看看结果:

Linux文件的权限与属性

(touch和mkdir指令分别用于创建空文件和空目录)

果然,结果和我们计算的一样!

  如果你想修改默认权限,直接使用umask指令后面接上数字来执行即可:

Linux文件的权限与属性

4. ACL细部权限设定:

  如果需要单独设置某个用户或某个群组对某个文件或某个目录的权限,则需要使用ACL(Access Control List)进行细部权限设定。可以使用setfacl命令进行设置,使用getfacl命令进行查询。

(1)查看当前系统是否支持ACL:

Linux文件的权限与属性

(2)设置单个用户对某个文件的权限:

Linux文件的权限与属性

(若用户名为空,则表示设置root用户对文件的权限;若设定权限为“-”则表示无权限)

(3)设置某个群组对某个文件的权限:

Linux文件的权限与属性

(4)有效权限设置:

Linux文件的权限与属性

(用户或群组所设定的权限必须要在mask的权限设定范围内才会生效)

  当使用以上命令给目录设置权限的时候,所设置的ACL权限都是无法被该目录下的子目录和文件所继承的,若想继承,则需下达命令格式为——setfacl -m d:u:账号:权限 目录名称。若在设置目录的ACL权限时,希望连同目录下的文件与子目录也一起设置则使用命令——setfacl -R u:账号:权限 目录名称。

  设置ACL权限之后还可以移除,移除全部ACL权限使用指令——setfacl -b 文件名称,移除某个账号的ACL权限使用指令——setfacl -x u:账号 文件名称。

二、时间属性

  在Linux中,每个文件与目录都有许多时间属性,其中有三个主要的时间属性:mtime(modification time)、atime(access time)、ctime(status time),分别表示文件内容最后修改时间、文件内容最后访问时间、文件状态(例如权限、属性)最后改变时间。

  ll(ls -l)命令默认展示的是mtime,我们可以通过指定--time选项来查看其它两个时间属性,而且默认展示的是简写的时间,我们可以通过指定--full-time选项来查看完整的时间:

Linux文件的权限与属性

(这里使用三个指令按顺序分别展示了mtime、atime和ctime)

  若想修改文件的时间属性,可以使用touch指令,例如我们来修改上图的“temp”文件的时间属性(有多种选项参数,这里只展示-t选项的使用):

Linux文件的权限与属性

可以看到,文件的mtime和atime已经被我们改为-t选项指定的时间了,但是ctime并没有,而是变成了我刚刚执行这个touch命令的时间。注意,ctime的意义是文件状态的最后改变时间,这里的文件状态包括权限、属性等,我们刚才改变了文件的mtime和atime这两个时间属性,所以文件状态的最后改变时间就是刚刚没错啊哈哈。注意,即使我们复制一个文件的时候复制了所有的属性,也无法复制ctime这个属性的!

三、连接数

  ll(ls -l)这个命令打印出来的结果中第二列数据表示的就是文件的连接数了,那么什么是文件或目录的连接数?它又是怎么计算出来的呢?这就要从硬连接和软连接说起了。由于硬连接涉及到Linux文件系统结构的问题,尤其是inode和data block的概念,所以如果不了解的可以先参考一下我的另一篇博文——Linux的文件系统结构(以下对硬连接的讲解是建立在读者已经了解这方面知识的基础上进行的)。

  什么是硬连接呢?假设现在已有一个文件A,它的连接数是1,那么我们可以在某个目录B下面建立文件A的硬连接C,这个建立硬连接的过程其实就是在目录B的data block中添加一条“硬连接C的文件名到文件A的inode编号”的关联记录,仅此而已,并没有真正创建新的文件。硬连接建立之后,就有两个文件名指向文件A的inode了,分别是文件A和硬连接文件C,所以文件A的连接数就变成了2,也就是说ll命令中展示的连接数实际上表示的就是硬连接数,每建立多一个硬连接,连接数就会增加1。下面我们就使用ln这个命令来创建一个硬连接看看效果:

Linux文件的权限与属性

这里我们创建了文件myfile的硬连接myfile2,可以看到,myfile的连接数增加了1,而且这两个文件的权限、属性都是一模一样的,这是因为文件的权限、属性都是存储在inode中的,而这两个文件名指向的是同一个inode啊,它们的文件内容也会是相同的,实际上就是同一个文件来的。

  那软连接又是什么呢?软连接其实就类似windows中的快捷方式。假设现在已有一个文件A,我们要在某个目录中创建文件A的软连接B,其实就是创建一个新的文件B,只是文件B的data block中仅仅记录了文件A的路径位置,打开文件B的时候就会读取到文件A的位置然后打开文件A。我们可以通过ln -s来创建一个软连接:

Linux文件的权限与属性

这里我们创建了文件myfile的软连接myfile3,可以看到,软连接对源文件的连接数并没有影响的,myfile3的文件大小为6个字节,这是因为它记录了源文件的名称“myfile”,6个字符,刚好6个字节!

  现在来总结一下硬连接与软连接的异同点:

(1)都可以使用ln指令来创建,只是创建软连接的时候要加上-s选项。

(2)打开硬连接和软连接最终都是打开源文件。

(3)创建1个硬连接会使源文件的连接数增加1,而创建软连接则不会。

(4)创建硬连接并不会创建新文件,而创建软连接则会新建一个文件。

(5)源文件删除之后,硬连接不会失效,而软连接会失效。

(6)硬连接不能跨文件系统,不能连接目录。

  最后补充一点,关于目录的连接数。我们新建一个空目录的时候,目录中默认就有“.”和“..”两个子目录,其中“.”目录指向了当前目录的inode,而“..”指向了上一层目录的inode。所以当我们创建一个新的空目录的时候,它的连接数是2,而上一层目录的连接数会增加1。

四、隐藏属性

  文件的隐藏属性主要是在系统安全方面起到作用,我们可以使用chattr命令来设置隐藏属性,而使用lsattr来查询。chattr指令的选项参数有很多,但比较常用的有两个:a和i,这两个属性都是只有root才能设置的,设置a表示这个文件只能增加内容而不能删除也不能修改,设置i表示文件不能被删除、改名、创建连接,也无法添加内容和修改内容,反正就是不能做任何改动!下面是设置与查询操作示例:

Linux文件的权限与属性

(+表示增加某个属性,-表示减去某个属性)

五、文件类型

  回到本文第一个ll(ls -l)指令的截图,ll指令打印的信息中第一列第一个字符表示的就是文件类型,不同的字符表示的文件类型不同:

-:普通文件(包括硬连接)。

d:目录。

l:软连接。

b:区块设备文件。

c:字符设备文件。

s:资料接口文件(sockets)。

p:资料输送文件(FIFO,pipe)。

可以使用file指令来查看某个文件具体的文件类型:

Linux文件的权限与属性

六、文件大小

  ll(ls -l)指令输出的第5列信息表示的就是文件大小,ll指令默认展示的文件大小都以byte(字节)为单位,可以使用-h参数将其展示成k、M、G为单位的形式:

Linux文件的权限与属性

其中total 16K表示这个目录中所有文件大小总和。

  然而我们会发现这些文件大小加起来并没有达到16K这么多啊:4k+60bytes+15bytes+15bytes=4k+90bytes<16k,怎么回事呢?如果大家对Linux文件系统结构有所了解就会知道怎么回事了,同样可以参考我的另一篇博文——Linux的文件系统结构。其实这里的16K表示的并不是所有文件真实大小的总和,而是所有文件占用磁盘空间的总和,我们知道即使一个文件很小,但它至少都会占用一个data block的。我们可以在ll指令添加-s选项查看各个文件占用的磁盘空间大小:

Linux文件的权限与属性

4k+4k+4k+4k=16k!是的,这里的第一列表示的就是每个文件占用的磁盘空间大小了,而第六列表示的则是每个文件内容的真实大小。从这里也可以看出我的Linux系统的每个data block大小为4K。

七、文件名称

  ll(ls -l)指令输出的最后一列信息表示的就是文件名称。其实文件名称本身并没有什么好说的,只是关于文件名称引申出来的一些问题需要记录一下。首先是隐藏文件问题,Linux的隐藏文件不像windows的隐藏文件那样需要进行属性设置的,它只是纯粹根据文件名称来决定文件是否隐藏,若文件名称以“.”开头则隐藏,否则显示。默认情况下我们使用ls指令是查看不到这些隐藏文件的,可以加上-a选项来查看所有文件。

  另外,Linux的文件也没有什么所谓的后缀名。比如一个文件是否为执行文件,根本与它是什么后缀名没关系,只是与文件的x执行权限有关罢了。不过我们可以在文件名后面加上一些适当的后缀名,使得我们能借此了解文件大概是什么内容的,只是这个后缀名没有什么实际用处就是了。