犀利小猫

日积月累 滴水石穿

导航

文件权限说明(Linux)

 不管是Linux新手还是高手,在使用它的时候不可避免都会遇到Linux权限问题。而这些问题也是初学者问得最多的问题,很多的脚本不能执行的原因就是因为没有设定正确的权限所致。这里我们来看看Linux下的根限到底是怎么一回事。
  当你新建一个文件时,它的最初的权限取决于你的umask值(将在后面说明)。权限可以使用chmod命令或是chmod()系统调用来修改一个文件的权限模式。只有在文件所有者才能修改文件的权限模式。唯一例外的就是超级用户:超级用户可以修改任何文件的权限。下面是chmod命令的格式:

chmod [-Rfh] [agou] [ -=] [rwxXstugol] filelist



要修改哪些用户的特权:
字符 含义
a 修改所有用户的特权
g 修改组用户的特权
o 修改其它用户的特权
u 修改所有者的权限
执行什么操作:
字符 含义
- 删除当前的权限
= 替换当前的权限
增加当前的权限
要修改哪一项权限:
字符 含义
r 读访问
w 写访问
x 执行访问
s SUID或是SGID
t 粘附位

SUID 是 Set User ID, SGID 是 Set Group ID的意思。)

  其中X是表示由BSD衍生出来的UNIX系统特有的选项,它的意思是:如果文件是一个目录,或有一些其它执行位已设置,那么就将文件设置为只可执行。而l则是由System V衍生出来的UNX系统特有的选项,它的意思是:允许对文件进行强制加锁。
-R选项表示chmod命令会递归执行。如果指定了一个目录filelist,那么目录的权限改变了,目录下所有文件的权限也都改变了。如果该目录包含子目录,那么这一地程会一直向下重复。
-f选项表示强制执行,chmod命令不会报告错误。通常在shell中比较有用。
  在某些系统中使用-h选项来改变chmod对符号链接的工作方式。如果指定了-h选项,而其中一个参数据为符号链接的话,那么chmod不会改变符号链接所指向的那个文件或目录的权限。
下图说明了命令的使用方法:

计算机八进制的文件权限:
  chmod允许用户使用一个四位八进制数字来指定文件权限模式。用户可以通过将权限相加的方式来计算这一数值。下表说明了每个文件权限对应的八进制数。

八进制数 权限
4000 SUID
2000 SGID
1000 粘附位
0400 所有者可读
0200 所有者可写
0100 所有者可执行
0040 组成员可读
0020 组成员可写
0010 组成员可执行
0004 其它用户可读
0002 其它用户可写
001 其它用户可执行
  因此,一个文件权限如果为“-rwxr-x---”,那么其文件模式为0750,计算过程为:0400 0200 0100 0040 0010=0750。例如常见的/tmp目录的权限就为1777,表示任何用户都可以在该目录下创建文件,但是用户不能删除其它用户的文件。

umask
  umask是“用户文件创建模式掩码”的缩写,是一个四位的八进制数值。用来确定一个新创建文件的权限。每个进程都从父进程那里继承了自己的umask。一般该命令会在.bashrc,.profile,.cshrc或是/etc/profile及/etc/bashrc中。

  最常见的umask值是022,027以及077。022让文件所有者拥有对新建文件的读写权限,但是其它人对此只读。例如:0666(默认的文件建立模式) 0022(umask)=0644。计算umask值最简单的方法是记住:umask值中的2屏蔽了写权限,而7屏蔽了读,写及执行权限。
常用的umask设置:
umask 用户访问 组访问 其它
0000 所有 所有 所有
0002 所有 所有 读,执行
0007 所有 所有
0022 所有 读,执行 读,执行
0027 所有 读,执行
0077 所有

  下面的图片是显示新建文件后的权限,大家可以想想看它对应的mask应是多少。

粘附位:
  具有八进制值1000的位叫粘附位,是unix已经发展得不再需要的事物而又不能摆脱其追随的例子.像unix在其上度过它的孩童期的PDP-11/70这样的小内存系统,需要一些程序持续地驻留在内存或交换设备上这个时候粘附位就十分重要了.在今天由于有了25美圆的内存模块和快速磁盘驱动器,在可执行程序上的粘附位已经过时了,现代的内核已经悄然地忽略了它.
  如果在目录上设置了这个位,那么大多数版本的unix不允许删除或重新命名该目录中的文件,除非你是该目录的属主,该文件的属主或超级用户.在这个目录上拥有写入权限是不够的.这相约定是让像/tmp之类的目录变得多少有些隐私性和安全性的一种尝试.


  Solaris和HP-UX在处理粘附位目录的时候并不那么严格.如果对该目录有写入权限,即使不是属主,也能删除其中的文件.这实际上有许多意义,虽然对实际应用几乎没有什么影响。 SUID和SGID   setuid和setgid的位值是04000和02000。这些位允许程序访问运它们的用户本来无权访问的文件和进程。当某个目录上设置setgid位时,在这个目录中新创建的文件具有该目录的属组权而不是创建该文件的用户的默认属组。这项约定使得在几个用户之间(只要这些用户都属于同一个组)共享一个目录中的文件变得更简单。在使用这些特性之前,请检查自己的系统,因为并不是所有版本的unix都支持这个特性,当然BSD,REDHAT,HP-UX,SOLARIS都是支持的。对setgid位的这种解释跟它在可执行文件上设置时的含义没有什么关系,但不要混淆了这两种意义。一些系统允许在非可执行的纯文本文件上设置setgid位,以在该文件被打开时请求特殊的锁定。有关它的详细说明可以参考:http://www.linuxeden.com/html/unix/20071031/36892.html。在linux下,有关SUID最常用的一个命令就是ping,下面是关于它的图片,好好看看吧。    如果对windows比较熟悉的人应对“runas”这个命令不会陌生,我个人觉得SUID及SGID和它有点类似,不过比它要更先进一点。runas允许非特权用户可以用管理员的用户来临时运行特殊的应用程序。不过这个命令在个人计算机上用得比较少,倒是在服务器上用得多一点。使用它在一定的程度可以增加安全性。     怎么样,有了一个相对直观的概念了吧,当然这里只是简单的列出这些,更深入的技术还需要过一步的学习和了解。

(第二篇)

文件的存取权限—模式位疑难详解
2004-04-23 15:18 pm
作者:Julian Chang
来自:无名

   一、前言
   ========

   本文主要说明Linux下普通文件及目录的存取权限设置。本文是为稍具基础的初学者写的(我也是beginner),如
   果您能够理解如下几行'ls -l'命令的输出含义(注意下面标注^的位),那您就没有必要读本文了——别浪费时
   间看对你没用的东西,时间是最宝贵的!

-r-sr-xr-x   1 root     bin         26975 Jun 24  1999 01:32 /usr/bin/passwd-----------1.1
   ^ 
-rwxrwSr-x   1 zyd      zyd         12506 Oct 29 10:27 test_euid-----------------------1.2
      ^
drwxrwxrwt   5 root     root         1024 Nov  1 17:17 01;34 /tmp----------------------1.3
^^^^     ^   ^
-rwxr-xr-x   2 zyd      zyd         32506 Oct 19 10:20 hard_link-----------------------1.4
             ^
lrwxr-xr-x   1 zyd      zyd         1 Oct 23 10:40 sym_link->/tmp/sym_target-----------1.5
^                                                            ^^^^^^^^^^^^^^^



   二、'ls -l'命令输出格式简介
   ===========================

   'ls -l'命令以长格式显示文件列表,其各字段含义如下:

lrwxr-xr-x   1 zyd      users         15 Oct 23 10:40 sym_link->/tmp/sym_target
 _________     ___      _____            ____________ ________  _______________
|    |       |  |         |            |       |          |            |
|    |       |  |         |            |       |          |            +--符号连接(s_link)
|    |       |  |         |            |       |          |
|    |       |  |         |            |       |          +-----文件名(name)
|    |       |  |         |            |       |
|    |       |  |         |            |       +----文件最后更改时间(time)
|    |       |  |         |            |
|    |       |  |         |            +------------以字节计的文件长度(size)
|    |       |  |         |
|    |       |  |         +----------文件属组(group)
|    |       |  |
|    |       |  +--------------------文件属主(user)
|    |       |
|    |       +-------连接数位(count)
|    |
|    +-------文件模式位(mode),占9位
|
+------------文件类型位(type),占一位

   以上9个字段中除了s_link外,其他字段对不同文件和目录都应该有。其中user、group、time和name的含义自
   明,本文就不再介绍,其它字段将分专题小节在本文介绍。


   三、文件类型(type)

   Linux支持的文件类型主要包括一下7类,箭头右面的字符就是相应的文件类型位标志:
   1、普通文件========>-
   2、目录文件========>d
   3、符号连接========>l
   4、字符设备文件====>c
   5、块设备文件======>b
   6、命名管道FIFO
   7、套接口socket

   其中FIFO和socket超出了本文的范畴,不做介绍。其它文件简单解释如下:

   1、普通文件:就是普通文件(废话!),你用'vi myfile'建立的myfile就是普通文件,比如可执行二进制代码
   文件、script脚本文件、ASCII文本文件、数据文件、配置文件......就解释到这样行吗?

   2、目录文件:目录可以理解成放其它文件和/或其它目录的容器,是一种特殊文件,其内容由目录项组成,每个
   目录项主要包括两部分内容:文件名name和索引节点号inode,两者和起来称为连接,我们将在下小节对inode
   进行更详细的介绍。

   3、设备文件:不知道诸位是否有使用DOS的经验,如果我们的机器只有三个DOS系统文件IO.SYS, MSDOS.SYS,
   COMMAND.COM,而你需要编辑一份英文文档,日后再通过打印机输出,你能怎么办?

   COPY CON MYDOC.TXT

   ;在此输入文档内容

   ^+D ;结束存盘

   COPY MYDOC.TXT > PRN ;打印文档

   如果你熟悉这个过程,那你就已经理解设备文件了。以上的CON和PRN分别是DOS定义的两个设备文件,分别对应
   终端和并行打印口。这种设计使我们不必了解设备使用的具体硬件细节,按使用普通文件相同的方法来使用外部
   设备。


   Linux下的设备文件分为三大类:字符设备、块设备和网络设备,要想准确区别它们可能需要单独写一篇更臭更
   长的文章,大致情况是:字符设备是直接读取的,不使用缓冲区,象串行口、终端等;而块设备都是通过缓冲区
   进行读取的,并且每次只能读取一定数量的块,比如磁盘每次至少要读取一个扇区(如512字节),块设备可以实
   现随机读写;网络设备即前面提到的socket,因为我还不很熟悉,就不乱说了。设备文件一般都保存在/dev目
   录下,诸位可以用ls -l命令看看都有什么?反正本文的重点在于介绍普通文件和目录,设备文件不是重点,所
   以就只介绍到这里。


   四、索引节点、硬连接和连接计数
   ==============================

   1、索引节点inode:

   Linux为每个文件分配一个称为索引节点的号码inode,可以将inode简单理解成一个指针,它永远指向本文件的
   具体存储位置。系统是通过索引节点(而不是文件名)来定位每一个文件。例如:

   假设我们在硬盘当前目录下建立了一个名为mytext文本文件,其内容只有一行:
   This is my file.
   当然这行文字一定是存储在磁盘数据区某个具体位置里(物理上要通过磁头号、柱面号和扇区号来描述,在本例
   中假设分别是1、20、30)。
   假设其inode是262457,那么系统通过一段标准程序,就能将这个inode转换成存放此文件的具体物理地址(1磁
   头、20柱面、30扇区),最终读出文件的内容:“This is my file.”
   所以inode是指向一个文件数据区的指针号码,一个inode对应着系统中唯一的一片物理数据区,而位于两个不
   同物理数据区的文件必定分别对应着两个不同的inode号码。

   文件拷贝命令:
   # cp /home/zyd/mytext newfile
   在当前工作目录建立了一个新文件newfile,其实际操作主要包括如下三步:
   1、在当前目录中增加一个目录项,其文件名域填入newfile,并分配了一个新的inode,假设是262456。
   2、将原文件(在1磁头、20柱面、30扇区)的内容复制了一份到新的空闲物理块(假设是1磁头、20柱面、31扇
   区)。
   3、填写一些其他关键信息,使系统通过这些信息及inode号码可以完成物理地址的转换。

   所以文件复制要分配新的inode和新的数据区,虽然两个文件的内容是一样的。


   2、硬连接hardlink:
   我们实际使用文件时一般是通过文件名来引用的。通过上面的讨论,我们知道:1个inode号码肯定和一片完全
   属于一个文件的数据区一一对应。那么一个文件系统中两个或更多个不同的文件名能否对应同一个文件呢?答案
   是肯定的。我们知道inode号码是记录在文件名对应的目录项中的,我们可以使两个或多个文件的目录项具有相
   同的inode值,实际上就使它们对应着同一个文件。有几个目录项具有相同的inode号,我们就说这个文件有几
   个硬连接(hardlink),对于普通文件,ls -l命令的连接计数count域的数值就是本文件拥有的硬连接数。硬连
   接可以通过ln命令建立,例如:

   # ln /home/zyd/mytext hardlink_mytext
   就建立了一个新的文件hardlink_mytext,这个文件的inode同样是262457。建立硬连接实际上只是增加了一个
   目录项,但并复制文件数据区,原文件的数据区由两个文件共享。这一方面能够节约大量磁盘空间,同时可以保
   证两个文件能同步更新。

   'ls -il'可以显示文件的inode(在下面最左边):

   262456 -rw-rw-r-- 1 zyd zyd 17 Nov 3 14:52 newfile
   262457 -rw-rw-r-- 2 zyd zyd 17 Nov 3 14:50 hardlink_mytext
   262457 -rw-rw-r-- 2 zyd zyd 17 Nov 3 14:50 mytext


   3、连接计数count:

   前面我们介绍了,文件的连接计数域表明本系统中共有几个文件目录项的inode和本文件相同,也就是本文件共
   有几个硬连接。如上面的例子中hardlink_mytext和mytext文件的count值都是2。

   那么对于目录,其count域的含义是什么呢?目录的count同样表示共有多少个目录项指向此目录,不过要详细
   说明必须进一步解释VFS文件系统的结构,为简单起见,只要这样理解就行了:(count-2)等于本目录包含的直
   接子目录数(就是只包括儿子,不包括孙子啦!)。例如:如果一个目录/abc的count域为5,那么
   /abc目录一定包含3个子目录。

   至此我们已经介绍了普通文件、目录文件、设备文件、硬连接、连接计数、索引节点等非常重要的概念。

   4、进一步说明:

   硬连接文件实际上并不是一种新的文件类型,两个文件互为对方的硬连接。它们应该都是普通文件(谁能告诉
   我:其它类型的文件可以硬连接吗?)。两个文件除了名称或/和文件目录不同外,其它部分完全相同,更改了一
   个文件,另一个的文件长度、内容、更改时间等都将相应发生变化,更改了一个文件的权限位mode,另一个也会
   发生同样的变化。

   注意连接计数字段count,互为硬连接的两个文件的count值都是2,表明有两个inode指向同一文件的inode。
   当我们删除其中一个文件时,系统首先将(count-1)->count,如果结果是零,就将其目录项和数据区都删除,
   否则只将本目录项删除,数据区仍然保留,仍然可以通过另外的文件名访问。根据这个特性,可以通过为重要的
   文件建立硬连接的方法来防止其被误删除。

   一个文件系统允许的inode节点数是有限的,如果文件数量太多,即使每个文件都是0字节的空文件,系统最终
   也会因为节点空间耗尽而不能再创建文件。所以当发现不能建立文件时首先要考虑硬盘数据区是否还有空间(可
   通过du命令),其次还得检查节点空间。

   互为硬连接的多个文件必须位于同一个文件系统上。根设备及任何一个需要mount才能挂接进来的分区、软盘、
   NFS、光驱等都是一个独立的文件系统,每个文件系统有一个相应的设备号,不同文件系统中具有相同inode节
   点的文件间没有任何联系。系统则通过设备号和inode号的组合唯一确定一个文件。

   Linux之所以能支持多种文件系统,其实是由于Linux提供了一个虚拟文件系统VFS,VFS作为实际文件系统的上
   层软件,掩盖了实际文件系统底层的具体结构差异,为系统访问位于不同文件系统的文件提供了一个统一的接
   口。实际上许多文件系统并不具备inode结构,其目录结构也和以上的讨论不同,但通过VFS,系统均为其提供
   了虚拟一致的inode和目录项结构。所以,'ls -il'命令实际显示的inode应该是VFS inode,也就是说,
   inode是存在于内存中的数据结构,而不一定是实际的硬盘结构。但为Linux量身定做的ext2文件系统具备实际
   的inode和连接型目录项结构,所以,对于ext2文件系统,可以认为我们上面讨论的关于硬连接的概念是完全正
   确的。

   本节最后两段的说明如果您暂时理解不了也没关系,随着学习的深入,慢慢就能理解了。


   五、符号连接
   ============

   不同文件系统中的文件不能建立硬连接,但可以通过符号连接进行同步。符号连接是一种独立的文件类型,它有
   自己的数据区,但数据区的内容只是一个被它指向的文件的路径名。前言那节的例子1.5说明文件sym_link是一
   个指向/tmp/sym_target文件的符号连接,如果我们cat sym_link,系统自动将它指向的文件打开显示而不是
   显示sym_link文件本身,注意sym_link的文件长度是15,正是字符串/tmp/sym_target的长度。建立符号连接
   和建立硬连接一样使用ln命令,不过要加入'-s'选项:

   ln -s /home/zyd/file_system/mytext my_sym_link
   # ls -li my_sym_link
   262458 lrwxrwxrwx 1 zyd zyd 28 Nov 3 14:55 my_sym_link -> /home/zyd/file_system/mytext

   思考题:建立符号连接时一般都要输入目标文件的绝对路径,为什么? 
   (提示:假设我们想让用户在任意当前目录都能执行/usr/local/my_bin/myproc而运行如下命令:
   # cd /usr/local/bin
   # ln -s ../my_bin/myproc myproc)


   六、文件模式位mode
   ==================

   通过chmod命令可以改变用户对相应文件的存取权限。
   Linux系统用一个16位的字来存储每个文件的type和mode,其中高4位通过组合来决定文件的type,它是在文件
   创建时写入的,用户不能更改。下面介绍后面的12位模式位

 bit|11 10 9 |8  7  6 | 5  4  3 | 2  1  0 |
----|--------|--------|---------|---------|
    | X  X X |X  X  X | X  X  X | X  X  X |
----|--------|--------|---------|---------|
mode          r  w  x   r  w  x   r  w  x 



   将这12位分成4组,高位组(9,10,11位)每位都有特殊的含义,下面将具体说明。此高位组(6,7,8位)决定文件
   属主拥有的权限,再下一组决定文件属组成员对此文件拥有的权限,最低位组决定除了属主及属组以外的用户拥
   有的对此文件操作的权限。

   较低3组中每组从最低位到最高位分别是执行位、改写位和读取位,哪位置1表示有相关权限。例如第6位是1表示
   属主可以执行此文件,第4位是1同组其他用户可以改写此文件,第2位是1表示其它用户可以读此文件。每组的3
   位构成一位8进制数,可以将各权限位的组合通过3位8进制表示,例如:
   111 101 100表示成754,则命令:
   chmod 754 filename使文件的属主能读、写和执行filename文件,本组的其他用户可以读和执行此文件,但不
   能修改。其他用户则只能读该文件。

   第11位是SUID位,第10位是SGID位,第9位是粘附位。
   如果某个可执行文件设置了SUID位,则此文件运行时的进程将具备和此文件属主相同的权限。
   /usr/bin/passwd设置了SUID位且其属主是root,则任何用户运行它时,其进程就具备了root权限,这就是为
   什么普通用户也可以通过passwd命令更改自己的登陆口令的原因(实际就是改变/etc/shadow文件,只有root有
   权读写此文件).具备SUID位且属主可执行,则属主执行位显示s来代替没有SUID位的x,如果属主不能执行,则
   显示为大写的S。

   SGID和SUID含义相对应。设置SGID位且属组可执行,则属组执行位改成s显示,否则以S显示。

   粘附位根据其他用户是否可执行分别在ls -l时在其他用户执行位上显示成t或T。对于可执行文件,设置了粘附
   位可以使其第一次运行后在交换分区swap中保留正文的副本,由于交换分区的文件是连续存放的,所以下次运行
   时能较快调入内存。对于现代文件系统来说,这一功能已经没有什么实际意义了。

   如果对一个目录设置了粘附位,则只有对于该目录具有写许可权的用户且满足如下三个条件之一,才能删除或更
   名该目录下的文件:
   1、超级用户root。
   2、此目录的拥有者。
   3、拥有要被删除或更改名字的文件。
   这一特性被Linux使用到了/tmp目录上:任何人都可以使用该目录存储文件,但只有文件所有者和root可以删除
   或更名文件。

   最后要谈的是目录的读、写和执行位的准确含义
   初学者常常对目录的权限位理解得似是而非,原因主要在于对文件系统的确切结构不理解。
   r表示读目录,w表示写目录,而x表示搜索目录(注意不是执行目录)
   我们通过以上讨论已经知道目录实际是一种特殊文件,它由目录项构成,每个目录项包括该目录下一个文件的文
   件名和inode。所以读权限就是读目录项的权限,因此获得此目录所包含的文件名列表。同样写目录权限就是更
   改目录目录文件(增加、减少和更名目录项),实际就是能否在该目录建立、删除文件和为文件改名。搜索权限通
   俗点可以理解为进入目录对文件内容进行操作的权限,包括打开文件、获取文件的进一步详细信息等权力。更通
   俗点,我们可以将目录比喻为盛药的盒子,我们在一个大药盒(根目录)上贴上叫“药品”的标签(目录名),下面
   列着“青霉素”和“感冒药”(目录项),拥有x权限相当于有打开这个盒子的钥匙。如果我们拥有钥匙,就能打
   开这个盒子(拥有根目录的x权限,可以进入),打开后发现里面还有一个加锁的盒子贴有“感冒药”标签(子目
   录),下面列着“感冒通”、“感康”......,另外还有一个药瓶里面装有消炎药青霉素(文件)。
   如果我们需要服用“青霉素”(相当于打开根目录下的文件),则我们必须拥有开大箱子的钥匙(根目录x权限)和
   吃药的权力(相应文件权限),但如果我们需要服用“感康”,则必须还有下一把钥匙。目录读权限相当于我们是
   否识字,写权限相当于我们是否拥有一只笔。只要识字,我们没有任何钥匙也能大致了解大箱子内有什么,但无
   法了解小盒子里有些什么具体药品。如果需要了解就必须首先能打开大箱子。如果我们要向大箱子内放入一种新
   药或拿出一种药品(相当于在根目录内创建、删除文件),我们首先必须能进入大箱子(x),然后有笔(w)能相应
   更改大箱子的标签。
   有了以上的比喻,下面进行正式说明:
   1、当我们打开任何文件时(也就是我们的命令中包含最终文件名时),对该文件名的绝对路径中的每个目录均必
   须拥有x搜索权限。也只有拥有了x权限,才能用cd命令进入该目录。
   2、读权限允许我们通过ls命令获得该目录的文件名列表,但前提仍然是必须对该目录的所有上级目录拥有x权限
   (想想药盒的故事)。
   3、在满足目录权限的前提下,最终对文件的读、写、执行取决于文件权限。
   4、只要你拥有一个目录的写权限及其所有上层目录的搜索权限,你就能在该目录建立文件和删除文件,即使这
   个文件不归你所有!!!
   5、超级用户可以超越大多数文件权限的检查。

   思考题:
   1、为什么目录建立的默认权限是rwxr-xr-x?
   2、假设在你的当前目录下有一个子目录test,你拥有读和写权限,没有搜索权限,如下命令哪些能够成功执
   行?为什么?
   ls test
   ls -l test
   cd test
   cp /etc/passwd ./test/newpasswd
   del test/new_file
   ln test/new_file up_file


   七、更改文件模式mode
   ====================

   更改文件模式可以通过chmod命令进行,我们将mode的低12位每3位一组组成4位8进制数,被设置权限的位为1,
   否则为0,作为chmod的参数之一,后面跟需要更改权限的文件名列表,例如:

   # chmod 4752 this.file
   设置了this.file的SUID位(4),文件属主可以读、写和执行(7)、同组其他用户可以读和执行,不能更改(5)、
   其他用户只能改写、不能读和执行(2)——哪位真的这样设置了权限位,肯定脑筋有点问题:)

   (全文完)

   ======================================== 一点说明 ======================================

   我接触Linux还不满1年,UNIX则从未见过,又刚刚学习编程,文中错误和不当之处难免,欢迎各位指正。

   Julian Chang
   julian_ch@bigfoot.com
   2000年11月20日

 

posted on 2011-12-15 08:44  犀利小猫  阅读(141)  评论(0编辑  收藏  举报