Linux 文件权限学习笔记

2023-10-31
次阅读
8 分钟阅读时长

在 Linux 中,文件权限分为所有者、群组、其他人三种身份。

  • 所有者:指拥有该文件/目录的用户,默认是创建该文件/目录的用户。
  • 群组:指该文件/目录所属的群组,默认是创建该文件/目录的用户所在主要群组。群组是多个用户的集合,通过给群组赋予权限,从而使群组中的用户都拥有相应的权限。
  • 其他人:如果一个用户既不是文件/目录的所有者,也不属于文件/目录所属的群组,那么该用户就是其他人。

在下面的例子中,可以看到当前用户是 her-cat,通过 ll 查看 /var/run/docker.sock 的文件属性。其中,第三列表示文件的所有者root第四列表示文件所属的群组是的 docker;用户 her-cat 既不是所有者 root,又不在 docker 群组中,所以用户 her-cat 的对该文件来说身份是其他人

[her-cat@centos her-cat]$ ll /var/run/docker.sock
srw-rw---- 1 root docker 0 9月  10 22:51 /var/run/docker.sock

上面的第一列 srw-rw---- 表示该文件的类型和权限,一共由 10 个字符组成。其中,第一个字符用来表示文件的类型,有以下几种类型:

  • d:表示为目录。
  • -:表示为普通文件。
  • l:表示为链接文件。
  • b:表示为设备文件中可供储存的设备。
  • c:表示为设备文件中的序列埠设备,例如键盘、鼠标。
  • s:表示为套接字文件。
  • p:表示为用于管道通信的文件。

在上面的例子中,第一个字符是 s, 所以该文件是一个套接字文件。

剩余 9 个字符 rw-rw---- 用来表示文件的权限,将其拆分成三个字符为一组,一共三组,即 rw-rw----,分别表示所有者、群组、其他人的权限。其中,每一组中的 3 个字符分别表示可读(r)、可写(w)、可执行(x),当拥有某项权限时,就会在相应的位置展示该权限对应的占位符(r/w/x),否则就会用 - 表示没有该项权限。

第一组的 rw- 表示所有者的权限,第一个字符 r 和第二个字符用 w 表示所有者拥有可读和可写权限,第三个字符是 - 而不是 x,表示所有者没有可执行权限。

第二组的 rw- 表示群组的权限,它与第一组相同,表示群组中的用户都拥有可读、可写权限,同样也没有可执行权限。

第三组的 --- 表示其他人的权限,与前两组不同,第三组的可读、可写、可执行都是 -,这意味着其他人没有可读、可写、可执行权限,也就是说除了所有者和群组中的用户以外,其他人不能对该文件进行任何操作。

在前面有提到,当前登录的用户是 her-cat,对应的是其他人的权限,所以我们不能对该文件执行任何操作,如果尝试读取该文件的内容,那么就会提示你没有权限读取该文件。

[her-cat@centos her-cat]$ cat /var/run/docker.sock
cat: /var/run/docker.sock: Permission denied

思考:为什么我们没有该文件的任何权限,却能看到这个文件呢?🤔

那么,作为当前用户要怎样才能拥有对该文件的操作权限呢?

我们可以从三种不同的身份下手,相应的就有以下四种方法。

  • 第一种:修改文件的所有者。

我们可以使用 chown 命令来修改文件的所有者,当我们是文件的所有者时,我们也就拥有了所有者所拥有的权限(可读、可写)。该命令的用法如下:

chown = change owner

chown [-R] 用户名 文件或目录

-R 表示递归修改目录下所有文件及目录的所有者。

使用示例:

sudo chown her-cat /var/run/docker.sock

再次查看文件属性,可以看到所有者已经是 her-cat 了。

[her-cat@centos her-cat]$ ll /var/run/docker.sock
srw-rw---- 1 her-cat docker 0 9月  10 22:51 /var/run/docker.sock

当然,由于这种方法比较「邪恶」,相当于本来是别人的东西,你直接开了「金手指」给抢过来,所以非必要情况,不建议使用该方法。

  • 第二种:修改文件所属的群组。

既然当前用户并不在该文件所属的群组 docker 中,那么我们将该文件所属的群组改成当前用户在的群组即可。

使用 groups 命令查看当前用户所属的群组。

[her-cat@centos her-cat]$ groups
her-cat adm wheel video

选择其中的一个为目标群组,例如 wheel,然后使用命令修改文件所属的群组,可以修改文件所属群组的命令有以下两个。

第一个命令就是上面提到的 chown,该命令除了可以修改文件的所有者以外,还可以用来修改文件所属的群组,用法如下:

chown [-R] :群组名 文件或目录 
chown [-R] 用户名:群组名 文件或目录 

两种用法并没有太大差异,只不过第二种可以同时修改所有者和群组。

使用示例:

sudo chown root:wheel /var/run/docker.sock

再次查看文件属性,可以看到所属群组已经是 wheel 了。

[her-cat@centos her-cat]$ ll /var/run/docker.sock
srw-rw---- 1 root wheel 0 9月  10 22:51 /var/run/docker.sock

第二个命令是专门用来修改群组的 chgrp,用法如下:

chgrp [-R] 用户组 文件或目录

使用示例:

sudo chgrp wheel /var/run/docker.sock

当然,修改群组的这种方法与修改所有者有「异曲同工」的感觉,所以,同样也是非必要不建议使用。

  • 第三种:修改其他人的权限。

前两种方法都有些太过于「粗暴」了,其操作的影响范围都很大,既然当前用户属于「其他人」,那我们只需要修改该文件对于「其他人」的权限即可。

我们可以使用 chmod 命令来修改文件的权限,该命令有两种符号和数字两种用法。

先来看第一种用法,使用符号来表示身份和权限,这种用法更适合我们人类进行阅读和理解,并且可操作性更强,它支持新增、修改、删除权限,下面我们来看一下如何使用。

chmod 命令中,分别使用 u、g、o 三个符号表示所有者、群组和其他人三种身份,还有一个特殊的 a 表示所有身份。我们可以对这些身份执行 +(新增)、-(删除)、=(修改)三个操作,相应的可读、可写和可执行权限就分别由 r、w 和 x 表示。

例如,我们现在要给所有者加上可执行权限,删除群组的可写权限,给其他人加上可读可写权限。

sudo chmod u+x,g-w,o+rw /var/run/docker.sock

查看文件属性:

[her-cat@centos her-cat]$ ll /var/run/docker.sock
srwxr--rw- 1 root docker 0 9月  10 22:51 /var/run/docker.sock

可以看到,所有者的权限由 rw- 变成了 rwx,群组的权限由 rw- 变成了 r--,其他人的权限由 --- 变成了 rw-,说明权限按照我们的预期修改成功了。

如果想要给所有身份都加上可写权限,那么只需要像下面这样即可:

sudo chmod a+w /var/run/docker.sock

第二种用法则是使用数字来表示身份和权限。

在这种用法中,分别使用 4、2、1、0 来表示 r(可读)、 w(可写)、x(可执行)和 -(没有权限),将每个身份的权限对应的数字加起来,最后得到的三个数字就是权限值。

例如当权限为 rwxr--rw-,所有者的权限 rwx 转换为数字是 421,将三个数字相加得到数字 7,那么 7 就表示所有者的权限;接下来是群组的权限 r--,转换为数字是 400,相加后为 4;最后是其他人的权限 rw-,转换为数字是 420,相加后得到 6;最后将每个身份的数字拼在一起就得到了权限值 746

所以,当我们使用 746 作为 chmod 的参数时,就可以将文件的权限设置为 rwxr--rw-

sudo chmod 746 /var/run/docker.sock

文件属性:

[her-cat@centos her-cat]$ ll /var/run/docker.sock
srwxr--rw- 1 root docker 0 9月  10 22:51 /var/run/docker.sock

如果想要给群组加上可写权限,可写权限 w 对应的数字是 2,在原来 4 基础上加 2 就得到了群组修改后的权限对应的数值 6,最后与所有者和其他人的数字拼在一起就得到了权限值 766。执行 chmod 命令时使用该权限值就可以将群组的权限修改为 rw-

由于每个身份的权限的数字不会重复,所以我们可以快速的知道数字所表示的权限。例如 7 就是 4 + 2 + 1,表示拥有所有权限(可读、可写、可执行),6 就是 4 + 2,表示拥有读写权限,不可能会是 2 + 2 + 2 这样的组合,因为可写权限只能出现一次。

虽然修改其他人权限相比前两种方法更「友好」,但是该方法依然存在一些弊端。

第一,在一些情况下该方法的作用是临时的。例如上面举例使用的 /var/run/docker.sock 文件,当机器重启后该文件会被清理,再次启动 Docker,你会发现该文件依然是原来的权限。所以我们每次重启机器后,都必须重新进行授权。

第二,存在安全风险。当我们给该文件的其他人增加了读写权限后,那么就意味着系统中所有的其他用户(不是所有者并且不在所属群组中的用户)都拥有了对该文件的读写权限,而不仅仅是给当前用户。

  • 第四种:加入文件所属的群组。

如果我们仅仅想让当前用户拥有权限,那么只需要将当前用户加入到文件所属的群组即可,这样就可以不修改文件本身的属性来达到获得权限的目的。

我们可以使用 usermod 命令将当前登录用户添加到 docker 群组中。

sudo usermod -aG docker her-cat

-G 表示将用户添加到指定的 docker 组中。 -a 表示在组中追加用户,而不是覆盖现有的用户。

查看当前用户所属的群组。

[her-cat@centos her-cat]$ groups
her-cat adm wheel video docker

可以看到已经添加成功了,但需要重新登录才能使其生效,如果在虚拟机中运行 Linux,则可能需要重新启动虚拟机才能使更改生效。

但是,我们也可以使用 newgrp 命令切换当前用户所属的群组,使其立即生效。用户可以同时属于多个群组,但在某一时刻只能以一个主群组的身份进行工作。

需要注意的是,newgrp 命令只会在当前会话中起作用,一旦退出当前会话,将恢复到在系统中定义的默认主群组。

newgrp docker

这时读取 /var/run/docker.sock 文件就不会提示无权限了。

以上就是文件权限相关的内容,接着来看下前面提到的问题:为什么我们没有该文件的任何权限,却能看到这个文件呢?

这是因为能否看到某个目录下的文件,与文件本身的权限无关,而是与文件所在的目录的权限有关。

目录权限与文件权限都是使用 r/w/x 进行表示,但是它们代表的含义不一样,下面是目录权限的 r/w/x 所代表的含义。

  • r:表示拥有读取该目录下的文件列表的权限。
  • w:表示拥有创建、删除、移动、重命名该目录下的文件的权限。
  • x:表示拥有进入目录作为工作目录的权限。

工作目录就是指当前所在的目录,使用 cd 命令进入某个目录的时候,就是将该目录作为工作目录。

从上面可以看出文件权限与目录权限的区别,文件权限针对的是对于文件内容的操作,而目录权限则针对的是文件本身,比如对移动文件、重命名文件等等,这些都是不会涉及文件内容的操作。

注意:本文中使用 /var/run/docker.sock 文件作为为例子,讲述了 Linux 文件权限相关概念及操作。建议在实际中不要使用该文件练习本文中的操作,以免出现问题。

本文作者:她和她的猫
本文地址https://her-cat.com/posts/2023/10/31/linux-file-permissions/
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!