3.6 文件权限、所有权和粘滞位

文件权限和所有权是UNIX/Linux文件系统(如ext文件系统)最显著的特性之一。在UNIX/Linux平台工作时,我们经常会碰到与文件权限及所有权相关的问题。这则攻略就考察了文件权限和所有权的不同用例。

3.6.1 预备知识

Linux系统中的每一个文件都与多种权限类型相关联。在这些权限中,我们通常要和三类权限打交道(用户、用户组以及其他实体)。

用户(user)是文件的所有者。用户组(group)是多个用户的集合,系统允许这些用户对文件进行某些形式的访问。其他用户(others)是除用户或用户组之外的任何用户。

用命令ls -l可以列出文件的权限:

  1. -rw-r--r-- 1 slynux slynux 2497 2010-02-28 11:22 bot.py
  2. -rw-r--r-- 1 slynux slynux 16237 2010-02-06 21:42 c9.php
  3. drwxr-xr-x 2 slynux slynux 4096 2010-05-27 14:31 a.py
  4. -rw-r--r-- 1 slynux slynux 539 2010-02-10 09:11 cl.pl

第1列输出明确了后面的输出。其中第一个字母的对应关系如下所示。

  • “-” —— 普通文件。

  • “d” —— 目录。

  • “c” —— 字符设备。

  • “b” —— 块设备。

  • “l” —— 符号链接。

  • “s” —— 套接字。

  • “p” —— 管道。

剩下的部分可以划分成三组,每组3个字符(————-)。第一组的3个字符(—-)对应用户权限(所有者),第二组对应用户组权限,第三组对应其他用户权限。这9个字符(即9个权限)中的每一个字符指明是否其设置了某种权限。如果设置了权限,对应位置上会出现一个字符,否则就以一个'-'表明没有设置对应的权限。

让我们来看一下每个字符组对用户、用户组以及其他用户的含义。

用户

权限序列:rwx------

第一个字符指定用户是否拥有文件的读权限。如果为用户设置了读权限,r将出现在第一个字符的位置上。第二个字符指定了写(修改)权限(w),第三个字符指定了用户是否拥有执行权限(x,即运行该文件的权限)。可执行文件通常会设置执行权限。用户还有一个称为setuidS)的特殊权限,它出现在执行权限(x)的位置。setuid权限允许用户以其拥有者的权限来执行可执行文件,即使这个可执行文件是由其他用户运行的。

具有setuid权限的文件的权限序列如下:

  1. -rwS------

目录同样也有读、写、执行权限。不过对于目录来说,读、写、执行权限的含义有点不一样。

  • 目录的读权限(r)允许读取目录中文件和子目录的列表。

  • 目录的写权限(w)允许在目录中创建或删除文件或目录。

  • 目录的执行权限(x)指明是否可以访问目录中的文件和子目录。

用户组

权限序列:---rwx---

第二组字符指定了组权限。组权限的rwx的含义和用户权限中的一样。组权限并没有setuid,但是有一个setgid位。它允许以同该目录拥有者所在组相同的有效组权限来允许可执行文件。但是这个组和实际发起命令的用户组未必相同。组权限的权限序列如下:

  1. ----rwS---

其他用户

权限序列:------rwx

最后三个字符是其他用户权限。和用户以及用户组一样,其他用户也有读、写、执行权限,但是并没有S权限(如setuidsetgid)。

目录有一个特殊的权限,叫做粘滞位(sticky bit)。当一个目录设置了粘滞位,只有创建该目录的用户才能删除目录中的文件,即使用户组和其他用户也有写权限。粘滞位出现在其他用户权限中的执行权限(x)位置。它使用tT来表示。如果没有设置执行权限,但设置了粘滞位,那么使用t;如果同时设置了执行权限和粘滞位,就使用T

例如:

  1. ------rwt , ------rwT

默认设置目录粘滞位的典型例子就是 /tmp。粘滞位属于一种写保护。

ls -l的每一行输出中,字符串slynux slynux对应所属用户和所属用户组。第一个slynux代表所属用户,第二个slynux代表用户组的所有者。

3.6.2 实战演练

为了设置文件权限,可使用chmod命令。

假设需要设置权限:rwx rw- r--

就可以使用chmod按照下面的方法设置:

  1. $ chmod u=rwx g=rw o=r filename

在这里:

  • u = 指定用户权限

  • g = 指定用户组权限

  • o = 指定其他实体权限

如果需要给文件添加权限,可以对用户、用户组和其他用户用 + 进行添加,用 - 删除权限。一个文件已经具有权限rwx rw- r--,现在需要增加可执行权限,方法如下:

  1. $ chmod o+x filename

给所有权限类别(即用户、用户组和其他用户)增加可执行权限:

  1. $ chmod a+x filename

其中,a表示全部(all)。

如果需要删除权限,则使用 -,例如:

  1. $ chmod a-x filename

也可以用八进制数来设置权限。权限由3位八进制数来表示,每一位按顺序分别对应用户、用户组和其他用户。

读、写和执行权限都有与之对应的唯一的八进制数:

  • r-- = 4

  • -w- = 2

  • --x = 1

我们可以将权限序列的八进制值相加来获得所需的权限组合,例如:

  • rw- = 4 + 2 = 6

  • r-x = 4 + 1 = 5

权限序列 rwx rw- r--的数字表示形式如下:

  • rwx = 4 + 2 + 1 = 7

  • rw- = 4 + 2 = 6

  • r-- = 4

因此,rwx rw- r-- 等于764,那么使用八进制值设置权限的命令为:

  1. $ chmod 764 filename

3.6.3 补充内容

让我们再看一些其他有关文件和目录的操作任务。

  • 更改所有权

要更改文件的所有权,可以使用chown命令:

  1. $ chown user.group filename

例如:

  1. $ chown slynux.slynux test.sh

在这里,slynux既是用户名,也是用户组名。

  • 设置粘滞位

粘滞位是一种应用于目录的权限类型。通过设置粘滞位,使得只有目录的所有者才能够删除目录中的文件,即使用户组和其他用户拥有足够的权限也不能执行该删除操作。

要设置粘滞位,利用chmod+t应用于目录:

  1. $ chmod a+t directory_name
  • 以递归的方式设置权限

有时候,要以递归的方式修改当前目录下的所有文件和子目录的权限,可以使用下面的方法:

  1. $ chmod 777 . -R

选项 -R指定以递归的方式修改权限。

我们用“.”指定当前工作目录,这等同于:

  1. $ chmod 777 "$(pwd)" -R.
  2. Sarath Lakshman 7 January 2011 8:41 PM
  • 以递归的方式设置所有权

chown命令结合 -R就可以以递归的方式设置所有权:

  1. $ chown user.group . -R
  • 以不同的用户运行可执行文件

一些可执行文件需要以不同的用户身份(除启动该文件的当前用户之外的用户),用文件路径来执行(如 ./executable_name)。有一个叫做setuid的特殊文件权限,它允许其他用户以文件所有者的身份来执行文件。

首先将该文件的所有权替换为该用户,这项操作每次都会执行,使该用户能以文件所有者的身份登录。然后运行下面的命令:

  1. $ chmod +s executable_file
  2.  
  3. # chown root.root executable_file
  4. # chmod +s executable_file
  5. $ ./executable_file

现在,这个文件实际上每次都是以超级用户的身份来执行。

setuid的使用不是无限制的。为了确保安全,它只能应用在Linux ELF格式二进制文件上,而不能用于脚本文件。